2017-10-04 03:08+0000, Jeremy Cline: > Make kvm_stat support Python 3 by changing the use of "print" to a > function rather than a statement, switching from "iteritems" and > "iterkeys" (removed in Python 3) to "items" and "keys" respectively, > and decoding bytes to strings when dealing with text. > > With this change, kvm_stat is usable with Python 2.6 and greater. > > Signed-off-by: Jeremy Cline <jeremy@xxxxxxxxxx> > --- > There were a few flaws in my original patch that changed the behavior in > Python 2. Additionally, I missed several compatibility problems with > Python 3. Sorry! No problem, you even sent a new version before I got to test it. :) Queued for 4.15, thanks. > Changes in v2: > - Include the "end=' '" argument in print statements that previously > had trailing commas since in Python 2 that causes the print > statement to not print a newline. > - decode bytes strings to text strings so that string concatenation > works properly in Python 3. > - replace "iterkeys" with "keys" as "iterkeys" is not in Python 3. > > tools/kvm/kvm_stat/kvm_stat | 30 +++++++++++++++++------------- > 1 file changed, 17 insertions(+), 13 deletions(-) > > diff --git a/tools/kvm/kvm_stat/kvm_stat b/tools/kvm/kvm_stat/kvm_stat > index 32283d88701a..217cf6f95c36 100755 > --- a/tools/kvm/kvm_stat/kvm_stat > +++ b/tools/kvm/kvm_stat/kvm_stat > @@ -19,9 +19,11 @@ Three different ways of output formatting are available: > > The data is sampled from the KVM's debugfs entries and its perf events. > """ > +from __future__ import print_function > > import curses > import sys > +import locale > import os > import time > import optparse > @@ -225,6 +227,8 @@ IOCTL_NUMBERS = { > 'RESET': 0x00002403, > } > > +ENCODING = locale.getpreferredencoding(False) > + > > class Arch(object): > """Encapsulates global architecture specific data. > @@ -666,7 +670,7 @@ class TracepointProvider(Provider): > """Returns 'event name: current value' for all enabled events.""" > ret = defaultdict(int) > for group in self.group_leaders: > - for name, val in group.read().iteritems(): > + for name, val in group.read().items(): > if name in self._fields: > ret[name] += val > return ret > @@ -955,7 +959,7 @@ class Tui(object): > except: > raise Exception > for line in child.stdout: > - line = line.lstrip().split(' ', 1) > + line = line.decode(ENCODING).lstrip().split(' ', 1) > # perform a sanity check before calling the more expensive > # function to possibly extract the guest name > if ' -name ' in line[1]: > @@ -1005,7 +1009,7 @@ class Tui(object): > name = '' > try: > line = open('/proc/{}/cmdline' > - .format(pid), 'rb').read().split('\0') > + .format(pid), 'r').read().split('\0') > parms = line[line.index('-name') + 1].split(',') > while '' in parms: > # commas are escaped (i.e. ',,'), hence e.g. 'foo,bar' results > @@ -1170,7 +1174,7 @@ class Tui(object): > .format(self.stats.fields_filter)) > self.screen.addstr(3, 0, "New regex: ") > curses.echo() > - regex = self.screen.getstr() > + regex = self.screen.getstr().decode(ENCODING) > curses.noecho() > if len(regex) == 0: > self.stats.fields_filter = DEFAULT_REGEX > @@ -1204,7 +1208,7 @@ class Tui(object): > > curses.echo() > self.screen.addstr(3, 0, "Pid [0 or pid]: ") > - pid = self.screen.getstr() > + pid = self.screen.getstr().decode(ENCODING) > curses.noecho() > > try: > @@ -1233,7 +1237,7 @@ class Tui(object): > self.screen.addstr(2, 0, 'Change delay from %.1fs to ' % > self._delay_regular) > curses.echo() > - val = self.screen.getstr() > + val = self.screen.getstr().decode(ENCODING) > curses.noecho() > > try: > @@ -1273,7 +1277,7 @@ class Tui(object): > self.print_all_gnames(7) > curses.echo() > self.screen.addstr(3, 0, "Guest [ENTER or guest]: ") > - gname = self.screen.getstr() > + gname = self.screen.getstr().decode(ENCODING) > curses.noecho() > > if not gname: > @@ -1369,25 +1373,25 @@ def batch(stats): > s = stats.get() > for key in sorted(s.keys()): > values = s[key] > - print '%-42s%10d%10d' % (key, values[0], values[1]) > + print('%-42s%10d%10d' % (key, values[0], values[1])) > except KeyboardInterrupt: > pass > > > def log(stats): > """Prints statistics as reiterating key block, multiple value blocks.""" > - keys = sorted(stats.get().iterkeys()) > + keys = sorted(stats.get().keys()) > > def banner(): > for k in keys: > - print '%s' % k, > - print > + print(k, end=' ') > + print() > > def statline(): > s = stats.get() > for k in keys: > - print ' %9d' % s[k][1], > - print > + print(' %9d' % s[k][1], end=' ') > + print() > line = 0 > banner_repeat = 20 > while True: > -- > 2.13.6 >