mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
python: Let RHashtable be returned as a Python dict.
The initial proposal was suggested by Matt Booth and discussed on the
mailing list here:
https://www.redhat.com/archives/libguestfs/2013-April/msg00007.html
(cherry picked from commit ba0199c487)
This commit is contained in:
@@ -581,7 +581,7 @@ and generate_python_py () =
|
||||
\"\"\"Python bindings for libguestfs
|
||||
|
||||
import guestfs
|
||||
g = guestfs.GuestFS ()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
g.add_drive_opts (\"guest.img\", format=\"raw\")
|
||||
g.launch ()
|
||||
parts = g.list_partitions ()
|
||||
@@ -642,9 +642,21 @@ class ClosedHandle(ValueError):
|
||||
class GuestFS:
|
||||
\"\"\"Instances of this class are libguestfs API handles.\"\"\"
|
||||
|
||||
def __init__ (self):
|
||||
\"\"\"Create a new libguestfs handle.\"\"\"
|
||||
def __init__ (self, python_return_dict=False):
|
||||
\"\"\"Create a new libguestfs handle.
|
||||
|
||||
Note about \"python_return_dict\" flag:
|
||||
|
||||
Setting this flag to 'True' causes all functions
|
||||
that internally return hashes to return a dict. This is
|
||||
natural for Python, and all new code should use
|
||||
python_return_dict=True.
|
||||
|
||||
If this flag is not present then hashes are returned
|
||||
as lists of pairs.
|
||||
\"\"\"
|
||||
self._o = libguestfsmod.create ()
|
||||
self._python_return_dict = python_return_dict
|
||||
|
||||
def __del__ (self):
|
||||
if self._o:
|
||||
@@ -654,6 +666,11 @@ class GuestFS:
|
||||
if not self._o:
|
||||
raise ClosedHandle (\"GuestFS: method called on closed handle\")
|
||||
|
||||
def _maybe_convert_to_dict (self, r):
|
||||
if self._python_return_dict == True:
|
||||
r = dict (r)
|
||||
return r
|
||||
|
||||
def close (self):
|
||||
\"\"\"Explicitly close the guestfs handle.
|
||||
|
||||
@@ -726,7 +743,7 @@ class GuestFS:
|
||||
| RStructList (_, typ) ->
|
||||
doc ^ sprintf "\n\nThis function returns a list of %ss. Each %s is represented as a dictionary." typ typ
|
||||
| RHashtable _ ->
|
||||
doc ^ "\n\nThis function returns a dictionary." in
|
||||
doc ^ "\n\nThis function returns a hash. If the GuestFS constructor was called with python_return_dict=True (recommended) then the return value is in fact a Python dict. Otherwise the return value is a list of pairs of strings, for compatibility with old code." in
|
||||
let doc =
|
||||
if List.mem ProtocolLimitWarning flags then
|
||||
doc ^ "\n\n" ^ protocol_limit_warning
|
||||
@@ -753,8 +770,20 @@ class GuestFS:
|
||||
pr " %s = list (%s)\n" n n
|
||||
) args;
|
||||
pr " self._check_not_closed ()\n";
|
||||
pr " return libguestfsmod.%s (self._o" name;
|
||||
pr " r = libguestfsmod.%s (self._o" name;
|
||||
List.iter (fun arg -> pr ", %s" (name_of_argt arg))
|
||||
(args @ args_of_optargs optargs);
|
||||
pr ")\n\n";
|
||||
pr ")\n";
|
||||
|
||||
(* For RHashtable, if self._python_return_dict=True then we
|
||||
* have to convert the result to a dict.
|
||||
*)
|
||||
(match ret with
|
||||
| RHashtable _ ->
|
||||
pr " r = self._maybe_convert_to_dict (r)\n";
|
||||
| _ -> ()
|
||||
);
|
||||
|
||||
pr " return r\n";
|
||||
pr "\n"
|
||||
) all_functions
|
||||
|
||||
@@ -5,7 +5,11 @@ import guestfs
|
||||
|
||||
output = "disk.img"
|
||||
|
||||
g = guestfs.GuestFS ()
|
||||
# All new Python code should pass python_return_dict=True
|
||||
# to the constructor. It indicates that your program wants
|
||||
# to receive Python dicts for methods in the API that return
|
||||
# hashtables.
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
# Create a raw-format sparse disk image, 512 MB in size.
|
||||
f = open (output, "w")
|
||||
|
||||
@@ -7,7 +7,7 @@ guestfs-python - How to use libguestfs from Python
|
||||
=head1 SYNOPSIS
|
||||
|
||||
import guestfs
|
||||
g = guestfs.GuestFS ()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
g.add_drive_opts ("disk.img", format="raw", readonly=1)
|
||||
g.launch ()
|
||||
|
||||
@@ -18,6 +18,17 @@ programming language. This page just documents the differences from
|
||||
the C API and gives some examples. If you are not familiar with using
|
||||
libguestfs, you also need to read L<guestfs(3)>.
|
||||
|
||||
=head2 python_return_dict=True
|
||||
|
||||
All new code should construct the handle using:
|
||||
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
This indicates that your program wants to receive Python dicts for
|
||||
methods in the API that return hashtables.
|
||||
|
||||
In a future version of libguestfs, this will become the default.
|
||||
|
||||
=head2 EXCEPTIONS
|
||||
|
||||
Errors from libguestfs functions are mapped into C<RuntimeException>
|
||||
|
||||
@@ -6,7 +6,11 @@ import guestfs
|
||||
assert (len (sys.argv) == 2)
|
||||
disk = sys.argv[1]
|
||||
|
||||
g = guestfs.GuestFS ()
|
||||
# All new Python code should pass python_return_dict=True
|
||||
# to the constructor. It indicates that your program wants
|
||||
# to receive Python dicts for methods in the API that return
|
||||
# hashtables.
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
# Attach the disk image read-only to libguestfs.
|
||||
g.add_drive_opts (disk, readonly=1)
|
||||
@@ -35,17 +39,10 @@ for root in roots:
|
||||
# Sort keys by length, shortest first, so that we end up
|
||||
# mounting the filesystems in the correct order.
|
||||
mps = g.inspect_get_mountpoints (root)
|
||||
def compare (a, b):
|
||||
if len(a[0]) > len(b[0]):
|
||||
return 1
|
||||
elif len(a[0]) == len(b[0]):
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
mps.sort (compare)
|
||||
for mp_dev in mps:
|
||||
def compare (a, b): return len(a) - len(b)
|
||||
for device in sorted (mps.keys(), compare):
|
||||
try:
|
||||
g.mount_ro (mp_dev[1], mp_dev[0])
|
||||
g.mount_ro (mps[device], device)
|
||||
except RuntimeError as msg:
|
||||
print "%s (ignored)" % msg
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import os
|
||||
import guestfs
|
||||
|
||||
g = guestfs.GuestFS()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
f = open ("test.img", "w")
|
||||
f.truncate (500 * 1024 * 1024)
|
||||
f.close ()
|
||||
|
||||
34
python/t/028-python-dict.py
Normal file
34
python/t/028-python-dict.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# libguestfs Python bindings
|
||||
# Copyright (C) 2013 Red Hat Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
# Test python-specific python_return_dict parameter.
|
||||
|
||||
from types import *
|
||||
import os
|
||||
import guestfs
|
||||
|
||||
g = guestfs.GuestFS (python_return_dict=False)
|
||||
|
||||
r = g.test0rhashtable ("5")
|
||||
if type(r) != list or r != [ ("0","0"), ("1","1"), ("2","2"), ("3","3"), ("4","4") ]:
|
||||
raise Exception ("python_return_dict=False: test0rhashtable returned %s" % r)
|
||||
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
r = g.test0rhashtable ("5")
|
||||
if type(r) != dict or sorted (r.keys()) != ["0","1","2","3","4"] or r["0"] != "0" or r["1"] != "1" or r["2"] != "2" or r["3"] != "3" or r["4"] != "4":
|
||||
raise Exception ("python_return_dict=True: test0rhashtable returned %s" % r)
|
||||
@@ -18,7 +18,7 @@
|
||||
import os
|
||||
import guestfs
|
||||
|
||||
g = guestfs.GuestFS()
|
||||
g = guestfs.GuestFS(python_return_dict=True)
|
||||
g.add_drive_opts ("/dev/null")
|
||||
g.add_drive_opts ("/dev/null", readonly = 1)
|
||||
g.add_drive_opts ("/dev/null", iface = "virtio", format = "raw")
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import os
|
||||
import guestfs
|
||||
|
||||
g = guestfs.GuestFS()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
def log_callback (ev,eh,buf,array):
|
||||
if ev == guestfs.EVENT_APPLIANCE:
|
||||
|
||||
@@ -20,13 +20,13 @@
|
||||
import os
|
||||
import guestfs
|
||||
|
||||
g = guestfs.GuestFS ()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
g.close () # explicit close
|
||||
del g # implicit close - should be no error/warning
|
||||
|
||||
# Expect an exception if we call a method on a closed handle.
|
||||
g = guestfs.GuestFS ()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
g.close ()
|
||||
try:
|
||||
g.set_memsize (512)
|
||||
@@ -37,7 +37,7 @@ del g
|
||||
|
||||
# Verify that the handle is really being closed by g.close, by setting
|
||||
# up a close event and testing that it happened.
|
||||
g = guestfs.GuestFS ()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
close_invoked = 0
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ f = open ("test.img", "w")
|
||||
f.truncate (500 * 1024 * 1024)
|
||||
f.close ()
|
||||
|
||||
g = guestfs.GuestFS ()
|
||||
g = guestfs.GuestFS (python_return_dict=True)
|
||||
|
||||
# Deliberate error: the disk format is supposed to be raw.
|
||||
g.add_drive_opts ("test.img", format="qcow2");
|
||||
|
||||
Reference in New Issue
Block a user