3 # generate python wrappers from the XML API description
9 enums
= {} # { enumType: { enumConstant: enumValue } }
10 lxc_enums
= {} # { enumType: { enumConstant: enumValue } }
11 qemu_enums
= {} # { enumType: { enumConstant: enumValue } }
20 #######################################################################
22 # That part if purely the API acquisition phase from the
23 # libvirt API description
25 #######################################################################
33 # Attach parser to an unmarshalling object. return both objects.
35 parser
= xml
.sax
.make_parser()
36 parser
.setContentHandler(target
)
39 class docParser(xml
.sax
.handler
.ContentHandler
):
41 self
._methodname
= None
45 self
.startElement
= self
.start
46 self
.endElement
= self
.end
47 self
.characters
= self
.data
53 def getmethodname(self
):
54 return self
._methodname
58 print("data %s" % text
)
59 self
._data
.append(text
)
61 def cdata(self
, text
):
63 print("data %s" % text
)
64 self
._data
.append(text
)
66 def start(self
, tag
, attrs
):
68 print("start %s, %s" % (tag
, attrs
))
73 self
.function_cond
= None
74 self
.function_args
= []
75 self
.function_descr
= None
76 self
.function_return
= None
77 self
.function_file
= None
78 self
.function_module
= None
79 if 'name' in attrs
.keys():
80 self
.function
= attrs
['name']
81 if 'file' in attrs
.keys():
82 self
.function_file
= attrs
['file']
83 if 'module' in attrs
.keys():
84 self
.function_module
= attrs
['module']
90 if self
.in_function
== 1:
91 self
.function_arg_name
= None
92 self
.function_arg_type
= None
93 self
.function_arg_info
= None
94 if 'name' in attrs
.keys():
95 self
.function_arg_name
= attrs
['name']
96 if self
.function_arg_name
== 'from':
97 self
.function_arg_name
= 'frm'
98 if 'type' in attrs
.keys():
99 self
.function_arg_type
= attrs
['type']
100 if 'info' in attrs
.keys():
101 self
.function_arg_info
= attrs
['info']
102 elif tag
== 'return':
103 if self
.in_function
== 1:
104 self
.function_return_type
= None
105 self
.function_return_info
= None
106 self
.function_return_field
= None
107 if 'type' in attrs
.keys():
108 self
.function_return_type
= attrs
['type']
109 if 'info' in attrs
.keys():
110 self
.function_return_info
= attrs
['info']
111 if 'field' in attrs
.keys():
112 self
.function_return_field
= attrs
['field']
114 # enums come from header files, hence virterror.h
115 if (attrs
['file'] == "libvirt" or
116 attrs
['file'] == "virterror" or
117 attrs
['file'] == "virerror"):
118 enum(attrs
['type'],attrs
['name'],attrs
['value'])
119 elif attrs
['file'] == "libvirt-lxc":
120 lxc_enum(attrs
['type'],attrs
['name'],attrs
['value'])
121 elif attrs
['file'] == "libvirt-qemu":
122 qemu_enum(attrs
['type'],attrs
['name'],attrs
['value'])
126 print("end %s" % tag
)
127 if tag
== 'function':
128 # fuctions come from source files, hence 'virerror.c'
129 if self
.function
is not None:
130 if (self
.function_module
== "libvirt" or
131 self
.function_module
== "event" or
132 self
.function_module
== "virevent" or
133 self
.function_module
== "virerror" or
134 self
.function_module
== "virterror"):
135 function(self
.function
, self
.function_descr
,
136 self
.function_return
, self
.function_args
,
137 self
.function_file
, self
.function_module
,
139 elif self
.function_module
== "libvirt-lxc":
140 lxc_function(self
.function
, self
.function_descr
,
141 self
.function_return
, self
.function_args
,
142 self
.function_file
, self
.function_module
,
144 elif self
.function_module
== "libvirt-qemu":
145 qemu_function(self
.function
, self
.function_descr
,
146 self
.function_return
, self
.function_args
,
147 self
.function_file
, self
.function_module
,
149 elif self
.function_file
== "python":
150 function(self
.function
, self
.function_descr
,
151 self
.function_return
, self
.function_args
,
152 self
.function_file
, self
.function_module
,
154 elif self
.function_file
== "python-lxc":
155 lxc_function(self
.function
, self
.function_descr
,
156 self
.function_return
, self
.function_args
,
157 self
.function_file
, self
.function_module
,
159 elif self
.function_file
== "python-qemu":
160 qemu_function(self
.function
, self
.function_descr
,
161 self
.function_return
, self
.function_args
,
162 self
.function_file
, self
.function_module
,
166 if self
.in_function
== 1:
167 self
.function_args
.append([self
.function_arg_name
,
168 self
.function_arg_type
,
169 self
.function_arg_info
])
170 elif tag
== 'return':
171 if self
.in_function
== 1:
172 self
.function_return
= [self
.function_return_type
,
173 self
.function_return_info
,
174 self
.function_return_field
]
179 if self
.in_function
== 1:
180 self
.function_descr
= str
185 if self
.in_function
== 1:
186 self
.function_cond
= str
189 def function(name
, desc
, ret
, args
, file, module
, cond
):
191 if onlyOverrides
and name
not in functions
:
193 if name
== "virConnectListDomains":
194 name
= "virConnectListDomainsID"
195 functions
[name
] = (desc
, ret
, args
, file, module
, cond
)
197 def qemu_function(name
, desc
, ret
, args
, file, module
, cond
):
199 if onlyOverrides
and name
not in qemu_functions
:
201 qemu_functions
[name
] = (desc
, ret
, args
, file, module
, cond
)
203 def lxc_function(name
, desc
, ret
, args
, file, module
, cond
):
205 if onlyOverrides
and name
not in lxc_functions
:
207 lxc_functions
[name
] = (desc
, ret
, args
, file, module
, cond
)
209 def enum(type, name
, value
):
210 if type not in enums
:
212 if value
== 'VIR_TYPED_PARAM_INT':
214 elif value
== 'VIR_TYPED_PARAM_UINT':
216 elif value
== 'VIR_TYPED_PARAM_LLONG':
218 elif value
== 'VIR_TYPED_PARAM_ULLONG':
220 elif value
== 'VIR_TYPED_PARAM_DOUBLE':
222 elif value
== 'VIR_TYPED_PARAM_BOOLEAN':
224 elif value
== 'VIR_DOMAIN_AFFECT_CURRENT':
226 elif value
== 'VIR_DOMAIN_AFFECT_LIVE':
228 elif value
== 'VIR_DOMAIN_AFFECT_CONFIG':
230 if onlyOverrides
and name
not in enums
[type]:
232 enums
[type][name
] = value
234 def lxc_enum(type, name
, value
):
235 if type not in lxc_enums
:
237 if onlyOverrides
and name
not in lxc_enums
[type]:
239 lxc_enums
[type][name
] = value
241 def qemu_enum(type, name
, value
):
242 if type not in qemu_enums
:
243 qemu_enums
[type] = {}
244 if onlyOverrides
and name
not in qemu_enums
[type]:
246 qemu_enums
[type][name
] = value
249 #######################################################################
251 # Some filtering rukes to drop functions/types which should not
252 # be exposed as-is on the Python interface
254 #######################################################################
256 functions_failed
= []
257 lxc_functions_failed
= []
258 qemu_functions_failed
= []
259 functions_skipped
= [
260 "virConnectListDomains",
262 lxc_functions_skipped
= []
263 qemu_functions_skipped
= []
269 # 'int *': "usually a return type",
270 'virConnectDomainEventCallback': "No function types in python",
271 'virConnectDomainEventGenericCallback': "No function types in python",
272 'virConnectDomainEventRTCChangeCallback': "No function types in python",
273 'virConnectDomainEventWatchdogCallback': "No function types in python",
274 'virConnectDomainEventIOErrorCallback': "No function types in python",
275 'virConnectDomainEventGraphicsCallback': "No function types in python",
276 'virConnectDomainQemuMonitorEventCallback': "No function types in python",
277 'virStreamEventCallback': "No function types in python",
278 'virEventHandleCallback': "No function types in python",
279 'virEventTimeoutCallback': "No function types in python",
280 'virDomainBlockJobInfoPtr': "Not implemented yet",
283 #######################################################################
285 # Table of remapping to/from the python type or class to the C
288 #######################################################################
291 'void': (None, None, None, None),
292 'int': ('i', None, "int", "int"),
293 'long': ('l', None, "long", "long"),
294 'double': ('d', None, "double", "double"),
295 'unsigned int': ('i', None, "int", "int"),
296 'unsigned long': ('l', None, "long", "long"),
297 'long long': ('L', None, "longlong", "long long"),
298 'unsigned long long': ('L', None, "longlong", "long long"),
299 'unsigned char *': ('z', None, "charPtr", "char *"),
300 'char *': ('z', None, "charPtr", "char *"),
301 'const char *': ('z', None, "constcharPtr", "const char *"),
302 'size_t': ('n', None, "size_t", "size_t"),
304 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
305 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
306 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
308 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
309 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
310 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
312 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
313 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
314 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
316 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
317 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
318 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
320 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
321 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
322 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
324 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
325 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
326 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
328 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
329 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
330 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
332 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
333 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
334 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
336 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
337 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
338 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
340 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
341 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
342 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
344 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
345 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
346 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
354 foreign_encoding_args
= (
357 #######################################################################
359 # This part writes the C <-> Python stubs libvirt.[ch] and
360 # the table libvirt-export.c to add when registrering the Python module
362 #######################################################################
364 # Class methods which are written by hand in libvirt.c but the Python-level
365 # code is still automatically generated (so they are not in skip_function()).
367 'virConnectGetVersion',
368 'virConnectGetLibVersion',
369 'virConnectListDomainsID',
370 'virConnectListDefinedDomains',
371 'virConnectListNetworks',
372 'virConnectListDefinedNetworks',
373 'virConnectListSecrets',
374 'virConnectListInterfaces',
375 'virConnectListStoragePools',
376 'virConnectListDefinedStoragePools',
377 'virConnectListStorageVols',
378 'virConnectListDefinedStorageVols',
379 'virConnectListDefinedInterfaces',
380 'virConnectListNWFilters',
381 'virDomainSnapshotListNames',
382 'virDomainSnapshotListChildrenNames',
383 'virConnGetLastError',
387 'virDomainGetControlInfo',
388 'virDomainGetBlockInfo',
389 'virDomainGetJobInfo',
390 'virDomainGetJobStats',
392 'virNodeGetSecurityModel',
393 'virDomainGetSecurityLabel',
394 'virDomainGetSecurityLabelList',
396 'virDomainGetUUIDString',
397 'virDomainLookupByUUID',
399 'virNetworkGetUUIDString',
400 'virNetworkLookupByUUID',
401 'virDomainGetAutostart',
402 'virNetworkGetAutostart',
403 'virDomainBlockStats',
404 'virDomainInterfaceStats',
405 'virDomainMemoryStats',
406 'virNodeGetCellsFreeMemory',
407 'virDomainGetSchedulerType',
408 'virDomainGetSchedulerParameters',
409 'virDomainGetSchedulerParametersFlags',
410 'virDomainSetSchedulerParameters',
411 'virDomainSetSchedulerParametersFlags',
412 'virDomainSetBlkioParameters',
413 'virDomainGetBlkioParameters',
414 'virDomainSetMemoryParameters',
415 'virDomainGetMemoryParameters',
416 'virDomainSetNumaParameters',
417 'virDomainGetNumaParameters',
420 'virDomainPinVcpuFlags',
421 'virDomainGetVcpuPinInfo',
422 'virDomainGetEmulatorPinInfo',
423 'virDomainPinEmulator',
427 'virSecretGetUUIDString',
428 'virSecretLookupByUUID',
429 'virNWFilterGetUUID',
430 'virNWFilterGetUUIDString',
431 'virNWFilterLookupByUUID',
432 'virStoragePoolGetUUID',
433 'virStoragePoolGetUUIDString',
434 'virStoragePoolLookupByUUID',
435 'virStoragePoolGetInfo',
436 'virStorageVolGetInfo',
437 'virStoragePoolGetAutostart',
438 'virStoragePoolListVolumes',
439 'virDomainBlockPeek',
440 'virDomainMemoryPeek',
441 'virEventRegisterImpl',
442 'virNodeListDevices',
443 'virNodeDeviceListCaps',
444 'virConnectBaselineCPU',
445 'virDomainRevertToSnapshot',
447 'virNodeGetCPUStats',
448 'virNodeGetMemoryStats',
449 'virDomainGetBlockJobInfo',
450 'virDomainMigrateGetCompressionCache',
451 'virDomainMigrateGetMaxSpeed',
452 'virDomainBlockStatsFlags',
453 'virDomainSetBlockIoTune',
454 'virDomainGetBlockIoTune',
455 'virDomainSetInterfaceParameters',
456 'virDomainGetInterfaceParameters',
457 'virDomainGetCPUStats',
458 'virDomainGetDiskErrors',
459 'virNodeGetMemoryParameters',
460 'virNodeSetMemoryParameters',
463 'virDomainMigrateToURI3',
464 'virConnectGetCPUModelNames',
465 'virNodeGetFreePages',
466 'virNetworkGetDHCPLeases',
470 'virDomainLxcOpenNamespace',
474 'virDomainQemuMonitorCommand',
475 'virDomainQemuAgentCommand',
479 # These are functions which the generator skips completly - no python
480 # or C code is generated. Generally should not be used for any more
481 # functions than those already listed
483 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
484 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
485 'virResetError', # Not used in Python API XXX is this a bug ?
486 'virGetVersion', # Python C code is manually written
487 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
488 'virConnCopyLastError', # Python API is called virConnGetLastError instead
489 'virCopyLastError', # Python API is called virGetLastError instead
490 'virConnectOpenAuth', # Python C code is manually written
491 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
492 'virConnectDomainEventRegister', # overridden in virConnect.py
493 'virConnectDomainEventDeregister', # overridden in virConnect.py
494 'virConnectDomainEventRegisterAny', # overridden in virConnect.py
495 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
496 'virConnectNetworkEventRegisterAny', # overridden in virConnect.py
497 'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py
498 'virSaveLastError', # We have our own python error wrapper
499 'virFreeError', # Only needed if we use virSaveLastError
500 'virConnectListAllDomains', # overridden in virConnect.py
501 'virDomainListAllSnapshots', # overridden in virDomain.py
502 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py
503 'virConnectListAllStoragePools', # overridden in virConnect.py
504 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py
505 'virConnectListAllNetworks', # overridden in virConnect.py
506 'virConnectListAllInterfaces', # overridden in virConnect.py
507 'virConnectListAllNodeDevices', # overridden in virConnect.py
508 'virConnectListAllNWFilters', # overridden in virConnect.py
509 'virConnectListAllSecrets', # overridden in virConnect.py
511 'virStreamRecvAll', # Pure python libvirt-override-virStream.py
512 'virStreamSendAll', # Pure python libvirt-override-virStream.py
513 'virStreamRecv', # overridden in libvirt-override-virStream.py
514 'virStreamSend', # overridden in libvirt-override-virStream.py
516 'virConnectUnregisterCloseCallback', # overridden in virConnect.py
517 'virConnectRegisterCloseCallback', # overridden in virConnect.py
519 'virDomainCreateXMLWithFiles', # overridden in virConnect.py
520 'virDomainCreateWithFiles', # overridden in virDomain.py
522 'virDomainFSFreeze', # overridden in virDomain.py
523 'virDomainFSThaw', # overridden in virDomain.py
524 'virDomainGetTime', # overridden in virDomain.py
525 'virDomainSetTime', # overridden in virDomain.py
527 # 'Ref' functions have no use for bindings users.
538 "virDomainSnapshotRef",
540 # This functions shouldn't be called via the bindings (and even the docs
541 # contain an explicit warning to that effect). The equivalent should be
542 # implemented in pure python for each class
543 "virDomainGetConnect",
544 "virInterfaceGetConnect",
545 "virNetworkGetConnect",
546 "virSecretGetConnect",
547 "virNWFilterGetConnect",
548 "virStoragePoolGetConnect",
549 "virStorageVolGetConnect",
550 "virDomainSnapshotGetConnect",
551 "virDomainSnapshotGetDomain",
553 # only useful in C code, python code uses dict for typed parameters
554 "virTypedParamsAddBoolean",
555 "virTypedParamsAddDouble",
556 "virTypedParamsAddFromString",
557 "virTypedParamsAddInt",
558 "virTypedParamsAddLLong",
559 "virTypedParamsAddString",
560 "virTypedParamsAddUInt",
561 "virTypedParamsAddULLong",
562 "virTypedParamsClear",
563 "virTypedParamsFree",
565 "virTypedParamsGetBoolean",
566 "virTypedParamsGetDouble",
567 "virTypedParamsGetInt",
568 "virTypedParamsGetLLong",
569 "virTypedParamsGetString",
570 "virTypedParamsGetUInt",
571 "virTypedParamsGetULLong",
573 'virNetworkDHCPLeaseFree', # only useful in C, python code uses list
576 lxc_skip_function
= (
577 "virDomainLxcEnterNamespace",
578 "virDomainLxcEnterSecurityLabel",
580 qemu_skip_function
= (
581 #"virDomainQemuAttach",
582 'virConnectDomainQemuMonitorEventRegister', # overridden in -qemu.py
583 'virConnectDomainQemuMonitorEventDeregister', # overridden in -qemu.py
586 # Generate C code, but skip python impl
587 function_skip_python_impl
= (
588 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't
589 # be exposed in bindings
592 lxc_function_skip_python_impl
= ()
593 qemu_function_skip_python_impl
= ()
595 function_skip_index_one
= (
596 "virDomainRevertToSnapshot",
599 def print_function_wrapper(module
, name
, output
, export
, include
):
604 global qemu_functions
605 global skipped_modules
606 global function_skip_python_impl
609 if module
== "libvirt":
610 (desc
, ret
, args
, file, mod
, cond
) = functions
[name
]
611 if module
== "libvirt-lxc":
612 (desc
, ret
, args
, file, mod
, cond
) = lxc_functions
[name
]
613 if module
== "libvirt-qemu":
614 (desc
, ret
, args
, file, mod
, cond
) = qemu_functions
[name
]
616 print("failed to get function %s infos" % name
)
619 if module
in skipped_modules
:
622 if module
== "libvirt":
623 if name
in skip_function
:
625 if name
in skip_impl
:
626 # Don't delete the function entry in the caller.
628 elif module
== "libvirt-lxc":
629 if name
in lxc_skip_function
:
631 if name
in lxc_skip_impl
:
632 # Don't delete the function entry in the caller.
634 elif module
== "libvirt-qemu":
635 if name
in qemu_skip_function
:
637 if name
in qemu_skip_impl
:
638 # Don't delete the function entry in the caller.
649 # This should be correct
650 if arg
[1][0:6] == "const ":
652 c_args
= c_args
+ " %s %s;\n" % (arg
[1], arg
[0])
653 if arg
[1] in py_types
:
654 (f
, t
, n
, c
) = py_types
[arg
[1]]
655 if (f
== 'z') and (name
in foreign_encoding_args
) and (num_bufs
== 0):
660 format_args
= format_args
+ ", &pyobj_%s" % (arg
[0])
661 c_args
= c_args
+ " PyObject *pyobj_%s;\n" % (arg
[0])
662 c_convert
= c_convert
+ \
663 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg
[0],
666 format_args
= format_args
+ ", &%s" % (arg
[0])
668 format_args
= format_args
+ ", &py_buffsize%d" % num_bufs
669 c_args
= c_args
+ " int py_buffsize%d;\n" % num_bufs
670 num_bufs
= num_bufs
+ 1
672 c_call
= c_call
+ ", "
673 c_call
= c_call
+ "%s" % (arg
[0])
675 if arg
[1] in skipped_types
:
677 if arg
[1] in unknown_types
:
678 lst
= unknown_types
[arg
[1]]
681 unknown_types
[arg
[1]] = [name
]
684 format
= format
+ ":%s" % (name
)
687 if file == "python_accessor":
688 if args
[1][1] == "char *":
689 c_call
= "\n VIR_FREE(%s->%s);\n" % (
690 args
[0][0], args
[1][0], args
[0][0], args
[1][0])
691 c_call
= c_call
+ " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args
[0][0],
692 args
[1][0], args
[1][1], args
[1][0])
694 c_call
= "\n %s->%s = %s;\n" % (args
[0][0], args
[1][0],
697 c_call
= "\n %s(%s);\n" % (name
, c_call
)
698 ret_convert
= " Py_INCREF(Py_None);\n return Py_None;\n"
699 elif ret
[0] in py_types
:
700 (f
, t
, n
, c
) = py_types
[ret
[0]]
701 c_return
= " %s c_retval;\n" % (ret
[0])
702 if file == "python_accessor" and ret
[2] is not None:
703 c_call
= "\n c_retval = %s->%s;\n" % (args
[0][0], ret
[2])
705 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
)
706 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
707 ret_convert
= ret_convert
+ " return py_retval;\n"
708 elif ret
[0] in py_return_types
:
709 (f
, t
, n
, c
) = py_return_types
[ret
[0]]
710 c_return
= " %s c_retval;\n" % (ret
[0])
711 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
)
712 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
713 ret_convert
= ret_convert
+ " return py_retval;\n"
715 if ret
[0] in skipped_types
:
717 if ret
[0] in unknown_types
:
718 lst
= unknown_types
[ret
[0]]
721 unknown_types
[ret
[0]] = [name
]
724 if cond
is not None and cond
!= "":
725 include
.write("#if %s\n" % cond
)
726 export
.write("#if %s\n" % cond
)
727 output
.write("#if %s\n" % cond
)
729 include
.write("PyObject * ")
730 if module
== "libvirt":
731 include
.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name
))
732 export
.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
734 elif module
== "libvirt-lxc":
735 include
.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name
))
736 export
.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" %
738 elif module
== "libvirt-qemu":
739 include
.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name
))
740 export
.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
744 # Those have been manually generated
745 if cond
is not None and cond
!= "":
746 include
.write("#endif\n")
747 export
.write("#endif\n")
748 output
.write("#endif\n")
750 if file == "python_accessor" and ret
[0] != "void" and ret
[2] is None:
751 # Those have been manually generated
752 if cond
is not None and cond
!= "":
753 include
.write("#endif\n")
754 export
.write("#endif\n")
755 output
.write("#endif\n")
758 output
.write("PyObject *\n")
759 if module
== "libvirt":
760 output
.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
761 elif module
== "libvirt-lxc":
762 output
.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
763 elif module
== "libvirt-qemu":
764 output
.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
765 output
.write(" PyObject *args")
767 output
.write(" ATTRIBUTE_UNUSED")
768 output
.write(") {\n")
770 output
.write(" PyObject *py_retval;\n")
772 output
.write(c_return
)
776 output
.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
777 (format
, format_args
))
778 output
.write(" return NULL;\n")
780 output
.write(c_convert
+ "\n")
782 output
.write(" LIBVIRT_BEGIN_ALLOW_THREADS;")
784 output
.write(" LIBVIRT_END_ALLOW_THREADS;\n")
785 output
.write(ret_convert
)
786 output
.write("}\n\n")
787 if cond
is not None and cond
!= "":
788 include
.write("#endif /* %s */\n" % cond
)
789 export
.write("#endif /* %s */\n" % cond
)
790 output
.write("#endif /* %s */\n" % cond
)
792 if module
== "libvirt":
793 if name
in function_skip_python_impl
:
795 elif module
== "libvirt-lxc":
796 if name
in lxc_function_skip_python_impl
:
798 elif module
== "libvirt-qemu":
799 if name
in qemu_function_skip_python_impl
:
803 def buildStubs(module
, api_xml
):
805 global py_return_types
809 if module
not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
810 print("ERROR: Unknown module type: %s" % module
)
813 if module
== "libvirt":
815 funcs_failed
= functions_failed
816 funcs_skipped
= functions_skipped
817 elif module
== "libvirt-lxc":
818 funcs
= lxc_functions
819 funcs_failed
= lxc_functions_failed
820 funcs_skipped
= lxc_functions_skipped
821 elif module
== "libvirt-qemu":
822 funcs
= qemu_functions
823 funcs_failed
= qemu_functions_failed
824 funcs_skipped
= qemu_functions_skipped
830 onlyOverrides
= False
831 (parser
, target
) = getparser()
835 msg
= sys
.exc_info()[1]
836 print(file, ":", msg
)
839 n
= len(list(funcs
.keys()))
841 print("Found %d functions in %s" % ((n
), api_xml
))
843 override_api_xml
= "%s-override-api.xml" % module
844 py_types
['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
847 f
= open(override_api_xml
)
851 (parser
, target
) = getparser()
855 msg
= sys
.exc_info()[1]
856 print(file, ":", msg
)
859 # XXX: This is not right, same function already in @functions
860 # will be overwritten.
861 print("Found %d functions in %s" % ((len(list(funcs
.keys())) - n
), override_api_xml
))
866 header_file
= "build/%s.h" % module
867 export_file
= "build/%s-export.c" % module
868 wrapper_file
= "build/%s.c" % module
870 include
= open(header_file
, "w")
871 include
.write("/* Generated */\n\n")
873 export
= open(export_file
, "w")
874 export
.write("/* Generated */\n\n")
876 wrapper
= open(wrapper_file
, "w")
877 wrapper
.write("/* Generated by generator.py */\n\n")
878 wrapper
.write("#include <Python.h>\n")
879 wrapper
.write("#include <libvirt/" + module
+ ".h>\n")
880 wrapper
.write("#include \"typewrappers.h\"\n")
881 wrapper
.write("#include \"build/" + module
+ ".h\"\n\n")
883 funcnames
= list(funcs
.keys())
884 if funcnames
is not None:
886 for function
in funcnames
:
887 # Skip the functions which are not for the module
888 ret
= print_function_wrapper(module
, function
, wrapper
, export
, include
)
891 funcs_failed
.append(function
)
894 skipped
= skipped
+ 1
895 funcs_skipped
.append(function
)
898 nb_wrap
= nb_wrap
+ 1
904 print("Generated %d wrapper functions" % nb_wrap
)
907 print("Missing type converters: ")
908 for type in list(unknown_types
.keys()):
909 print("%s:%d " % (type, len(unknown_types
[type])))
911 for f
in funcs_failed
:
912 print("ERROR: failed %s" % f
)
916 if len(unknown_types
) > 0:
920 #######################################################################
922 # This part writes part of the Python front-end classes based on
923 # mapping rules between types and classes and also based on function
924 # renaming to get consistent function names at the Python level
926 #######################################################################
929 # The type automatically remapped to generated classes
932 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
933 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
934 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
935 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
936 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
937 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
938 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
939 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
940 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
941 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
942 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
943 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
944 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
945 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
946 "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
947 "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
948 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
949 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
950 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
951 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
952 "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
953 "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
959 primary_classes
= ["virDomain", "virNetwork", "virInterface",
960 "virStoragePool", "virStorageVol",
961 "virConnect", "virNodeDevice", "virSecret",
962 "virNWFilter", "virStream", "virDomainSnapshot"]
967 classes_destructors
= {
968 "virDomain": "virDomainFree",
969 "virNetwork": "virNetworkFree",
970 "virInterface": "virInterfaceFree",
971 "virStoragePool": "virStoragePoolFree",
972 "virStorageVol": "virStorageVolFree",
973 "virNodeDevice" : "virNodeDeviceFree",
974 "virSecret": "virSecretFree",
975 "virNWFilter": "virNWFilterFree",
976 "virDomainSnapshot": "virDomainSnapshotFree",
977 # We hand-craft __del__ for this one
978 #"virStream": "virStreamFree",
981 class_skip_connect_impl
= {
985 class_domain_impl
= {
986 "virDomainSnapshot": True,
989 functions_noexcept
= {
990 'virDomainGetID': True,
991 'virDomainGetName': True,
992 'virNetworkGetName': True,
993 'virInterfaceGetName': True,
994 'virStoragePoolGetName': True,
995 'virStorageVolGetName': True,
996 'virStorageVolGetkey': True,
997 'virNodeDeviceGetName': True,
998 'virNodeDeviceGetParent': True,
999 'virSecretGetUsageType': True,
1000 'virSecretGetUsageID': True,
1001 'virNWFilterGetName': True,
1004 reference_keepers
= {
1007 function_classes
= {}
1009 function_classes
["None"] = []
1013 # Functions returning an integral type which need special rules to
1014 # check for errors and raise exceptions.
1015 functions_int_exception_test
= {
1016 'virDomainGetMaxMemory': "%s == 0",
1018 functions_int_default_test
= "%s == -1"
1020 def is_integral_type (name
):
1021 return not re
.search ("^(unsigned)? ?(int|long)$", name
) is None
1023 def is_optional_arg(info
):
1024 return re
.search("^\(?\optional\)?", info
) is not None
1025 # Functions returning lists which need special rules to check for errors
1026 # and raise exceptions.
1027 functions_list_exception_test
= {
1029 functions_list_default_test
= "%s is None"
1031 def is_python_noninteger_type (name
):
1033 return name
[-1:] == "*"
1035 def nameFixup(name
, classe
, type, file):
1036 # avoid a desastrous clash
1037 listname
= classe
+ "List"
1040 if name
[0:l
] == listname
:
1042 func
= func
[0:1].lower() + func
[1:]
1043 elif name
[0:16] == "virNetworkDefine":
1045 func
= func
[0:1].lower() + func
[1:]
1046 elif name
[0:19] == "virNetworkCreateXML":
1048 func
= func
[0:1].lower() + func
[1:]
1049 elif name
[0:16] == "virNetworkLookup":
1051 func
= func
[0:1].lower() + func
[1:]
1052 elif name
[0:18] == "virInterfaceDefine":
1054 func
= func
[0:1].lower() + func
[1:]
1055 elif name
[0:21] == "virInterfaceCreateXML":
1057 func
= func
[0:1].lower() + func
[1:]
1058 elif name
[0:18] == "virInterfaceLookup":
1060 func
= func
[0:1].lower() + func
[1:]
1061 elif name
[0:15] == "virSecretDefine":
1063 func
= func
[0:1].lower() + func
[1:]
1064 elif name
[0:15] == "virSecretLookup":
1066 func
= func
[0:1].lower() + func
[1:]
1067 elif name
[0:17] == "virNWFilterDefine":
1069 func
= func
[0:3].lower() + func
[3:]
1070 elif name
[0:17] == "virNWFilterLookup":
1072 func
= func
[0:3].lower() + func
[3:]
1073 elif name
[0:20] == "virStoragePoolDefine":
1075 func
= func
[0:1].lower() + func
[1:]
1076 elif name
[0:23] == "virStoragePoolCreateXML":
1078 func
= func
[0:1].lower() + func
[1:]
1079 elif name
[0:20] == "virStoragePoolLookup":
1081 func
= func
[0:1].lower() + func
[1:]
1082 elif name
[0:19] == "virStorageVolDefine":
1084 func
= func
[0:1].lower() + func
[1:]
1085 elif name
[0:19] == "virStorageVolLookup":
1087 func
= func
[0:1].lower() + func
[1:]
1088 elif name
[0:20] == "virDomainGetCPUStats":
1090 func
= func
[0:1].lower() + func
[1:]
1091 elif name
[0:12] == "virDomainGet":
1093 func
= func
[0:1].lower() + func
[1:]
1094 elif name
[0:29] == "virDomainSnapshotLookupByName":
1096 func
= func
[0:1].lower() + func
[1:]
1097 elif name
[0:26] == "virDomainSnapshotListNames":
1099 func
= func
[0:1].lower() + func
[1:]
1100 elif name
[0:28] == "virDomainSnapshotNumChildren":
1102 func
= func
[0:1].lower() + func
[1:]
1103 elif name
[0:20] == "virDomainSnapshotNum":
1105 func
= func
[0:1].lower() + func
[1:]
1106 elif name
[0:26] == "virDomainSnapshotCreateXML":
1108 func
= func
[0:1].lower() + func
[1:]
1109 elif name
[0:24] == "virDomainSnapshotCurrent":
1111 func
= func
[0:1].lower() + func
[1:]
1112 elif name
[0:17] == "virDomainSnapshot":
1114 func
= func
[0:1].lower() + func
[1:]
1115 elif name
[0:9] == "virDomain":
1117 func
= func
[0:1].lower() + func
[1:]
1118 elif name
[0:13] == "virNetworkGet":
1120 func
= func
[0:1].lower() + func
[1:]
1121 func
= func
.replace("dHCP", "DHCP")
1122 elif name
[0:10] == "virNetwork":
1124 func
= func
[0:1].lower() + func
[1:]
1125 elif name
[0:15] == "virInterfaceGet":
1127 func
= func
[0:1].lower() + func
[1:]
1128 elif name
[0:12] == "virInterface":
1130 func
= func
[0:1].lower() + func
[1:]
1131 elif name
[0:12] == 'virSecretGet':
1133 func
= func
[0:1].lower() + func
[1:]
1134 elif name
[0:9] == 'virSecret':
1136 func
= func
[0:1].lower() + func
[1:]
1137 elif name
[0:14] == 'virNWFilterGet':
1139 func
= func
[0:1].lower() + func
[1:]
1140 elif name
[0:11] == 'virNWFilter':
1142 func
= func
[0:1].lower() + func
[1:]
1143 elif name
[0:12] == 'virStreamNew':
1145 elif name
[0:9] == 'virStream':
1147 func
= func
[0:1].lower() + func
[1:]
1148 elif name
[0:17] == "virStoragePoolGet":
1150 func
= func
[0:1].lower() + func
[1:]
1151 elif name
[0:14] == "virStoragePool":
1153 func
= func
[0:1].lower() + func
[1:]
1154 elif name
[0:16] == "virStorageVolGet":
1156 func
= func
[0:1].lower() + func
[1:]
1157 elif name
[0:13] == "virStorageVol":
1159 func
= func
[0:1].lower() + func
[1:]
1160 elif name
[0:13] == "virNodeDevice":
1161 if name
[13:16] == "Get":
1162 func
= name
[16].lower() + name
[17:]
1163 elif name
[13:19] == "Lookup" or name
[13:19] == "Create":
1164 func
= name
[3].lower() + name
[4:]
1166 func
= name
[13].lower() + name
[14:]
1167 elif name
[0:7] == "virNode":
1169 func
= func
[0:1].lower() + func
[1:]
1170 elif name
[0:10] == "virConnect":
1172 func
= func
[0:1].lower() + func
[1:]
1173 elif name
[0:3] == "xml":
1175 func
= func
[0:1].lower() + func
[1:]
1182 if func
== "uUIDString":
1184 if func
== "oSType":
1186 if func
== "xMLDesc":
1188 if func
== "mACString":
1194 def functionSortKey(info
):
1195 (index
, func
, name
, ret
, args
, filename
, mod
) = info
1196 return func
, filename
1198 def writeDoc(module
, name
, args
, indent
, output
):
1199 if module
== "libvirt":
1201 elif module
== "libvirt-lxc":
1202 funcs
= lxc_functions
1203 elif module
== "libvirt-qemu":
1204 funcs
= qemu_functions
1205 if funcs
[name
][0] is None or funcs
[name
][0] == "":
1207 val
= funcs
[name
][0]
1208 val
= val
.replace("NULL", "None")
1209 output
.write(indent
)
1217 output
.write(indent
)
1219 output
.write(' """\n')
1221 def buildWrappers(module
):
1224 global py_return_types
1225 global unknown_types
1227 global function_classes
1230 global primary_classes
1231 global classes_ancestor
1232 global converter_type
1233 global classes_destructors
1234 global functions_noexcept
1236 if not module
== "libvirt":
1237 print("ERROR: Unknown module type: %s" % module
)
1240 for type in list(classes_type
.keys()):
1241 function_classes
[classes_type
[type][2]] = []
1244 # Build the list of C types to look for ordered to start
1245 # with primary classes
1249 ctypes_processed
= {}
1250 classes_processed
= {}
1251 for classe
in primary_classes
:
1252 classes_list
.append(classe
)
1253 classes_processed
[classe
] = ()
1254 for type in list(classes_type
.keys()):
1255 tinfo
= classes_type
[type]
1256 if tinfo
[2] == classe
:
1258 ctypes_processed
[type] = ()
1259 for type in list(classes_type
.keys()):
1260 if type in ctypes_processed
:
1262 tinfo
= classes_type
[type]
1263 if tinfo
[2] not in classes_processed
:
1264 classes_list
.append(tinfo
[2])
1265 classes_processed
[tinfo
[2]] = ()
1268 ctypes_processed
[type] = ()
1270 for name
in list(functions
.keys()):
1272 (desc
, ret
, args
, file, mod
, cond
) = functions
[name
]
1274 classe
= classes_type
[type][2]
1276 if name
[0:3] == "vir" and len(args
) >= 1 and args
[0][1] == type:
1278 func
= nameFixup(name
, classe
, type, file)
1279 info
= (0, func
, name
, ret
, args
, file, mod
)
1280 function_classes
[classe
].append(info
)
1282 elif name
[0:3] == "vir" and len(args
) >= 2 and args
[1][1] == type \
1283 and file != "python_accessor" and not name
in function_skip_index_one
:
1285 func
= nameFixup(name
, classe
, type, file)
1286 info
= (1, func
, name
, ret
, args
, file, mod
)
1287 function_classes
[classe
].append(info
)
1291 func
= nameFixup(name
, "None", file, file)
1292 info
= (0, func
, name
, ret
, args
, file, mod
)
1293 function_classes
['None'].append(info
)
1295 classes_file
= "build/%s.py" % module
1296 extra_file
= "%s-override.py" % module
1299 classes
= open(classes_file
, "w")
1301 if os
.path
.exists(extra_file
):
1302 extra
= open(extra_file
, "r")
1303 classes
.write("#\n")
1304 classes
.write("# WARNING WARNING WARNING WARNING\n")
1305 classes
.write("#\n")
1306 classes
.write("# This file is automatically written by generator.py. Any changes\n")
1307 classes
.write("# made here will be lost.\n")
1308 classes
.write("#\n")
1309 classes
.write("# To change the manually written methods edit " + module
+ "-override.py\n")
1310 classes
.write("# To change the automatically written methods edit generator.py\n")
1311 classes
.write("#\n")
1312 classes
.write("# WARNING WARNING WARNING WARNING\n")
1313 classes
.write("#\n")
1314 if extra
is not None:
1315 classes
.writelines(extra
.readlines())
1316 classes
.write("#\n")
1317 classes
.write("# WARNING WARNING WARNING WARNING\n")
1318 classes
.write("#\n")
1319 classes
.write("# Automatically written part of python bindings for libvirt\n")
1320 classes
.write("#\n")
1321 classes
.write("# WARNING WARNING WARNING WARNING\n")
1322 if extra
is not None:
1325 if "None" in function_classes
:
1326 flist
= function_classes
["None"]
1327 flist
.sort(key
=functionSortKey
)
1330 (index
, func
, name
, ret
, args
, file, mod
) = info
1332 classes
.write("#\n# Functions from module %s\n#\n\n" % file)
1334 classes
.write("def %s(" % func
)
1339 classes
.write("%s" % arg
[0])
1340 if arg
[0] == "flags" or is_optional_arg(arg
[2]):
1341 if is_integral_type(arg
[1]):
1344 classes
.write("=None")
1346 classes
.write("):\n")
1347 writeDoc(module
, name
, args
, ' ', classes
)
1350 if arg
[1] in classes_type
:
1351 classes
.write(" if %s is None: %s__o = None\n" %
1353 classes
.write(" else: %s__o = %s%s\n" %
1354 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1355 if ret
[0] != "void":
1356 classes
.write(" ret = ")
1359 classes
.write("libvirtmod.%s(" % name
)
1364 classes
.write("%s" % arg
[0])
1365 if arg
[1] in classes_type
:
1366 classes
.write("__o")
1368 classes
.write(")\n")
1370 if ret
[0] != "void":
1371 if ret
[0] in classes_type
:
1373 # Raise an exception
1375 if name
in functions_noexcept
:
1376 classes
.write(" if ret is None:return None\n")
1379 " if ret is None:raise libvirtError('%s() failed')\n" %
1382 classes
.write(" return ")
1383 classes
.write(classes_type
[ret
[0]][1] % ("ret"))
1386 # For functions returning an integral type there are
1387 # several things that we can do, depending on the
1388 # contents of functions_int_*:
1389 elif is_integral_type (ret
[0]):
1390 if name
not in functions_noexcept
:
1391 if name
in functions_int_exception_test
:
1392 test
= functions_int_exception_test
[name
]
1394 test
= functions_int_default_test
1395 classes
.write ((" if " + test
+
1396 ": raise libvirtError ('%s() failed')\n") %
1398 classes
.write(" return ret\n")
1400 elif is_python_noninteger_type (ret
[0]):
1401 if name
not in functions_noexcept
:
1402 if name
in functions_list_exception_test
:
1403 test
= functions_list_exception_test
[name
]
1405 test
= functions_list_default_test
1406 classes
.write ((" if " + test
+
1407 ": raise libvirtError ('%s() failed')\n") %
1409 classes
.write(" return ret\n")
1412 classes
.write(" return ret\n")
1416 for classname
in classes_list
:
1417 if classname
== "None":
1420 if classname
in classes_ancestor
:
1421 classes
.write("class %s(%s):\n" % (classname
,
1422 classes_ancestor
[classname
]))
1423 classes
.write(" def __init__(self, _obj=None):\n")
1424 if classname
in reference_keepers
:
1425 rlist
= reference_keepers
[classname
]
1427 classes
.write(" self.%s = None\n" % ref
[1])
1428 classes
.write(" self._o = _obj\n")
1429 classes
.write(" %s.__init__(self, _obj=_obj)\n\n" % (
1430 classes_ancestor
[classname
]))
1432 classes
.write("class %s(object):\n" % (classname
))
1433 if classname
in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1434 "virStorageVol", "virNodeDevice", "virSecret","virStream",
1436 classes
.write(" def __init__(self, conn, _obj=None):\n")
1437 elif classname
in [ 'virDomainSnapshot' ]:
1438 classes
.write(" def __init__(self, dom, _obj=None):\n")
1440 classes
.write(" def __init__(self, _obj=None):\n")
1441 if classname
in reference_keepers
:
1442 rlist
= reference_keepers
[classname
]
1444 classes
.write(" self.%s = None\n" % ref
[1])
1445 if classname
in [ "virDomain", "virNetwork", "virInterface",
1446 "virNodeDevice", "virSecret", "virStream",
1448 classes
.write(" self._conn = conn\n")
1449 elif classname
in [ "virStorageVol", "virStoragePool" ]:
1450 classes
.write(" self._conn = conn\n" + \
1451 " if not isinstance(conn, virConnect):\n" + \
1452 " self._conn = conn._conn\n")
1453 elif classname
in [ "virDomainSnapshot" ]:
1454 classes
.write(" self._dom = dom\n")
1455 classes
.write(" self._conn = dom.connect()\n")
1456 classes
.write(" self._o = _obj\n\n")
1458 if classname
in classes_destructors
:
1459 classes
.write(" def __del__(self):\n")
1460 classes
.write(" if self._o is not None:\n")
1461 classes
.write(" libvirtmod.%s(self._o)\n" %
1462 classes_destructors
[classname
])
1463 classes
.write(" self._o = None\n\n")
1464 destruct
=classes_destructors
[classname
]
1466 if classname
not in class_skip_connect_impl
:
1467 # Build python safe 'connect' method
1468 classes
.write(" def connect(self):\n")
1469 classes
.write(" return self._conn\n\n")
1471 if classname
in class_domain_impl
:
1472 classes
.write(" def domain(self):\n")
1473 classes
.write(" return self._dom\n\n")
1475 flist
= function_classes
[classname
]
1476 flist
.sort(key
=functionSortKey
)
1479 (index
, func
, name
, ret
, args
, file, mod
) = info
1481 # Do not provide as method the destructors for the class
1482 # to avoid double free
1484 if name
== destruct
:
1487 if file == "python_accessor":
1488 classes
.write(" # accessors for %s\n" % (classname
))
1490 classes
.write(" #\n")
1491 classes
.write(" # %s functions from module %s\n" % (
1493 classes
.write(" #\n\n")
1495 classes
.write(" def %s(self" % func
)
1499 classes
.write(", %s" % arg
[0])
1500 if arg
[0] == "flags" or is_optional_arg(arg
[2]):
1501 if is_integral_type(arg
[1]):
1504 classes
.write("=None")
1506 classes
.write("):\n")
1507 writeDoc(module
, name
, args
, ' ', classes
)
1510 if arg
[1] in classes_type
:
1512 classes
.write(" if %s is None: %s__o = None\n" %
1514 classes
.write(" else: %s__o = %s%s\n" %
1515 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1517 if ret
[0] != "void":
1518 classes
.write(" ret = ")
1522 classes
.write("libvirtmod.%s(" % name
)
1527 classes
.write("%s" % arg
[0])
1528 if arg
[1] in classes_type
:
1529 classes
.write("__o")
1531 classes
.write("self")
1532 if arg
[1] in classes_type
:
1533 classes
.write(classes_type
[arg
[1]][0])
1535 classes
.write(")\n")
1537 if name
== "virConnectClose":
1538 classes
.write(" self._o = None\n")
1540 # For functions returning object types:
1541 if ret
[0] != "void":
1542 if ret
[0] in classes_type
:
1544 # Raise an exception
1546 if name
in functions_noexcept
:
1548 " if ret is None:return None\n")
1550 if classname
== "virConnect":
1552 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1554 elif classname
== "virDomain":
1556 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1558 elif classname
== "virNetwork":
1560 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1562 elif classname
== "virInterface":
1564 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1566 elif classname
== "virStoragePool":
1568 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1570 elif classname
== "virStorageVol":
1572 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1574 elif classname
== "virDomainSnapshot":
1576 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1580 " if ret is None:raise libvirtError('%s() failed')\n" %
1584 # generate the returned class wrapper for the object
1586 classes
.write(" __tmp = ")
1587 classes
.write(classes_type
[ret
[0]][1] % ("ret"))
1591 # Sometime one need to keep references of the source
1592 # class in the returned class object.
1593 # See reference_keepers for the list
1595 tclass
= classes_type
[ret
[0]][2]
1596 if tclass
in reference_keepers
:
1597 rlist
= reference_keepers
[tclass
]
1599 if pref
[0] == classname
:
1600 classes
.write(" __tmp.%s = self\n" %
1603 # Post-processing - just before we return.
1604 if name
in function_post
:
1605 classes
.write(" %s\n" %
1606 (function_post
[name
]))
1611 classes
.write(" return __tmp\n")
1612 elif ret
[0] in converter_type
:
1614 # Raise an exception
1616 if name
in functions_noexcept
:
1618 " if ret is None:return None")
1620 # Post-processing - just before we return.
1621 if name
in function_post
:
1622 classes
.write(" %s\n" %
1623 (function_post
[name
]))
1625 classes
.write(" return ")
1626 classes
.write(converter_type
[ret
[0]] % ("ret"))
1629 # For functions returning an integral type there
1630 # are several things that we can do, depending on
1631 # the contents of functions_int_*:
1632 elif is_integral_type (ret
[0]):
1633 if name
not in functions_noexcept
:
1634 if name
in functions_int_exception_test
:
1635 test
= functions_int_exception_test
[name
]
1637 test
= functions_int_default_test
1638 if classname
== "virConnect":
1639 classes
.write ((" if " + test
+
1640 ": raise libvirtError ('%s() failed', conn=self)\n") %
1642 elif classname
== "virDomain":
1643 classes
.write ((" if " + test
+
1644 ": raise libvirtError ('%s() failed', dom=self)\n") %
1646 elif classname
== "virNetwork":
1647 classes
.write ((" if " + test
+
1648 ": raise libvirtError ('%s() failed', net=self)\n") %
1650 elif classname
== "virInterface":
1651 classes
.write ((" if " + test
+
1652 ": raise libvirtError ('%s() failed', net=self)\n") %
1654 elif classname
== "virStoragePool":
1655 classes
.write ((" if " + test
+
1656 ": raise libvirtError ('%s() failed', pool=self)\n") %
1658 elif classname
== "virStorageVol":
1659 classes
.write ((" if " + test
+
1660 ": raise libvirtError ('%s() failed', vol=self)\n") %
1663 classes
.write ((" if " + test
+
1664 ": raise libvirtError ('%s() failed')\n") %
1667 # Post-processing - just before we return.
1668 if name
in function_post
:
1669 classes
.write(" %s\n" %
1670 (function_post
[name
]))
1672 classes
.write (" return ret\n")
1674 elif is_python_noninteger_type (ret
[0]):
1675 if name
not in functions_noexcept
:
1676 if name
in functions_list_exception_test
:
1677 test
= functions_list_exception_test
[name
]
1679 test
= functions_list_default_test
1680 if classname
== "virConnect":
1681 classes
.write ((" if " + test
+
1682 ": raise libvirtError ('%s() failed', conn=self)\n") %
1684 elif classname
== "virDomain":
1685 classes
.write ((" if " + test
+
1686 ": raise libvirtError ('%s() failed', dom=self)\n") %
1688 elif classname
== "virNetwork":
1689 classes
.write ((" if " + test
+
1690 ": raise libvirtError ('%s() failed', net=self)\n") %
1692 elif classname
== "virInterface":
1693 classes
.write ((" if " + test
+
1694 ": raise libvirtError ('%s() failed', net=self)\n") %
1696 elif classname
== "virStoragePool":
1697 classes
.write ((" if " + test
+
1698 ": raise libvirtError ('%s() failed', pool=self)\n") %
1700 elif classname
== "virStorageVol":
1701 classes
.write ((" if " + test
+
1702 ": raise libvirtError ('%s() failed', vol=self)\n") %
1705 classes
.write ((" if " + test
+
1706 ": raise libvirtError ('%s() failed')\n") %
1709 # Post-processing - just before we return.
1710 if name
in function_post
:
1711 classes
.write(" %s\n" %
1712 (function_post
[name
]))
1714 classes
.write (" return ret\n")
1717 # Post-processing - just before we return.
1718 if name
in function_post
:
1719 classes
.write(" %s\n" %
1720 (function_post
[name
]))
1722 classes
.write(" return ret\n")
1725 # Append "<classname>.py" to class def, iff it exists
1728 extra
= open("libvirt-override-" + classname
+ ".py", "r")
1729 classes
.write (" #\n")
1730 classes
.write (" # %s methods from %s.py (hand coded)\n" % (classname
,classname
))
1731 classes
.write (" #\n")
1735 # Since we compile with older libvirt, we don't want to pull
1736 # in manually written python methods which call C methods
1737 # that don't exist. This code attempts to detect which
1738 # methods to skip by looking at the libvirtmod.XXXX calls
1740 def shouldSkip(lines
):
1742 offset
= line
.find("libvirtmod.")
1744 func
= line
[offset
+ 11:]
1745 offset
= func
.find("(")
1746 func
= func
[0:offset
]
1747 if func
not in functions_skipped
:
1751 for line
in extra
.readlines():
1752 offset
= line
.find(" def ")
1754 name
= line
[offset
+5:]
1755 offset
= name
.find("(")
1756 name
= name
[0:offset
]
1757 if cached
is not None:
1758 if not shouldSkip(cached
):
1759 classes
.writelines(cached
)
1760 if name
== "__del__":
1766 if cached
is not None:
1770 if not shouldSkip(cached
):
1771 classes
.writelines(cached
)
1778 # Generate enum constants
1780 def enumsSortKey(data
):
1785 value
= float('inf')
1788 enumvals
= list(enums
.items())
1789 if enumvals
is not None:
1790 enumvals
.sort(key
=lambda x
: x
[0])
1791 for type,enum
in enumvals
:
1792 classes
.write("# %s\n" % type)
1793 items
= list(enum
.items())
1794 items
.sort(key
=enumsSortKey
)
1795 if items
[-1][0].endswith('_LAST'):
1797 for name
,value
in items
:
1798 classes
.write("%s = %s\n" % (name
,value
))
1803 def qemuBuildWrappers(module
):
1804 global qemu_functions
1806 if not module
== "libvirt-qemu":
1807 print("ERROR: only libvirt-qemu is supported")
1810 extra_file
= "%s-override.py" % module
1813 fd
= open("build/libvirt_qemu.py", "w")
1815 if os
.path
.exists(extra_file
):
1816 extra
= open(extra_file
, "r")
1818 fd
.write("# WARNING WARNING WARNING WARNING\n")
1820 fd
.write("# This file is automatically written by generator.py. Any changes\n")
1821 fd
.write("# made here will be lost.\n")
1823 fd
.write("# To change the manually written methods edit " + module
+ "-override.py\n")
1824 fd
.write("# To change the automatically written methods edit generator.py\n")
1826 fd
.write("# WARNING WARNING WARNING WARNING\n")
1828 fd
.write("# Automatically written part of python bindings for libvirt\n")
1832 fd
.write(" import libvirtmod_qemu\n")
1833 fd
.write("except ImportError:\n")
1834 fd
.write(" lib_e = sys.exc_info()[1]\n")
1836 fd
.write(" import cygvirtmod_qemu as libvirtmod_qemu\n")
1837 fd
.write(" except ImportError:\n")
1838 fd
.write(" cyg_e = sys.exc_info()[1]\n")
1839 fd
.write(" if str(cyg_e).count(\"No module named\"):\n")
1840 fd
.write(" raise lib_e\n\n")
1842 fd
.write("import libvirt\n\n")
1843 fd
.write("# WARNING WARNING WARNING WARNING\n")
1845 if extra
is not None:
1846 fd
.writelines(extra
.readlines())
1848 if extra
is not None:
1851 fd
.write("# WARNING WARNING WARNING WARNING\n")
1853 fd
.write("#\n# Functions from module %s\n#\n\n" % module
)
1855 # Generate functions directly, no classes
1857 for name
in list(qemu_functions
.keys()):
1858 func
= nameFixup(name
, 'None', None, None)
1859 (desc
, ret
, args
, file, mod
, cond
) = qemu_functions
[name
]
1860 fd
.write("def %s(" % func
)
1865 fd
.write("%s" % arg
[0])
1868 writeDoc(module
, name
, args
, ' ', fd
)
1870 if ret
[0] != "void":
1874 fd
.write("libvirtmod_qemu.%s(" % name
)
1880 if arg
[1] == "virConnectPtr":
1885 if arg
[1] in ["virDomainPtr", "virConnectPtr"]:
1886 # FIXME: This might have problem if the function
1887 # has multiple args which are objects.
1888 fd
.write("%s.%s" % (arg
[0], "_o"))
1890 fd
.write("%s" % arg
[0])
1894 if ret
[0] != "void":
1895 fd
.write(" if ret is None: raise libvirt.libvirtError('" + name
+ "() failed')\n")
1896 if ret
[0] == "virDomainPtr":
1897 fd
.write(" __tmp = virDomain(" + conn
+ ",_obj=ret)\n")
1898 fd
.write(" return __tmp\n")
1900 fd
.write(" return ret\n")
1905 # Generate enum constants
1907 for type,enum
in list(qemu_enums
.items()):
1908 fd
.write("# %s\n" % type)
1909 items
= list(enum
.items())
1910 items
.sort(key
=lambda i
: int(i
[1]))
1911 for name
,value
in items
:
1912 fd
.write("%s = %s\n" % (name
,value
))
1918 def lxcBuildWrappers(module
):
1919 global lxc_functions
1921 if not module
== "libvirt-lxc":
1922 print("ERROR: only libvirt-lxc is supported")
1925 extra_file
= "%s-override.py" % module
1928 fd
= open("build/libvirt_lxc.py", "w")
1930 if os
.path
.exists(extra_file
):
1931 extra
= open(extra_file
, "r")
1933 fd
.write("# WARNING WARNING WARNING WARNING\n")
1935 fd
.write("# This file is automatically written by generator.py. Any changes\n")
1936 fd
.write("# made here will be lost.\n")
1938 fd
.write("# To change the manually written methods edit " + module
+ "-override.py\n")
1939 fd
.write("# To change the automatically written methods edit generator.py\n")
1941 fd
.write("# WARNING WARNING WARNING WARNING\n")
1943 if extra
is not None:
1944 fd
.writelines(extra
.readlines())
1946 fd
.write("# WARNING WARNING WARNING WARNING\n")
1948 fd
.write("# Automatically written part of python bindings for libvirt\n")
1950 fd
.write("# WARNING WARNING WARNING WARNING\n")
1951 if extra
is not None:
1955 fd
.write(" import libvirtmod_lxc\n")
1956 fd
.write("except ImportError:\n")
1957 fd
.write(" lib_e = sys.exc_info()[1]\n")
1959 fd
.write(" import cygvirtmod_lxc as libvirtmod_lxc\n")
1960 fd
.write(" except ImportError:\n")
1961 fd
.write(" cyg_e = sys.exc_info()[1]\n")
1962 fd
.write(" if str(cyg_e).count(\"No module named\"):\n")
1963 fd
.write(" raise lib_e\n\n")
1965 fd
.write("import libvirt\n\n")
1966 fd
.write("#\n# Functions from module %s\n#\n\n" % module
)
1968 # Generate functions directly, no classes
1970 for name
in list(lxc_functions
.keys()):
1971 func
= nameFixup(name
, 'None', None, None)
1972 (desc
, ret
, args
, file, mod
, cond
) = lxc_functions
[name
]
1973 fd
.write("def %s(" % func
)
1978 fd
.write("%s" % arg
[0])
1981 writeDoc(module
, name
, args
, ' ', fd
)
1983 if ret
[0] != "void":
1987 fd
.write("libvirtmod_lxc.%s(" % name
)
1993 if arg
[1] == "virConnectPtr":
1998 if arg
[1] in ["virDomainPtr", "virConnectPtr"]:
1999 # FIXME: This might have problem if the function
2000 # has multiple args which are objects.
2001 fd
.write("%s.%s" % (arg
[0], "_o"))
2003 fd
.write("%s" % arg
[0])
2007 if ret
[0] != "void":
2008 fd
.write(" if ret is None: raise libvirt.libvirtError('" + name
+ "() failed')\n")
2009 if ret
[0] == "virDomainPtr":
2010 fd
.write(" __tmp = virDomain(" + conn
+ ",_obj=ret)\n")
2011 fd
.write(" return __tmp\n")
2013 fd
.write(" return ret\n")
2018 # Generate enum constants
2020 for type,enum
in list(lxc_enums
.items()):
2021 fd
.write("# %s\n" % type)
2022 items
= list(enum
.items())
2023 items
.sort(key
=lambda i
: int(i
[1]))
2024 for name
,value
in items
:
2025 fd
.write("%s = %s\n" % (name
,value
))
2032 if not os
.path
.exists("build"):
2035 if buildStubs(sys
.argv
[1], sys
.argv
[2]) < 0:
2038 if sys
.argv
[1] == "libvirt":
2039 buildWrappers(sys
.argv
[1])
2040 elif sys
.argv
[1] == "libvirt-lxc":
2041 lxcBuildWrappers(sys
.argv
[1])
2042 elif sys
.argv
[1] == "libvirt-qemu":
2043 qemuBuildWrappers(sys
.argv
[1])
2045 print("ERROR: unknown module %s" % sys
.argv
[1])