public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo-x86 commit in dev-util/gprof2dot/files: gprof2dot-0_p20100216-python3.patch
@ 2012-03-15 20:16 Sebastian Pipping (sping)
  0 siblings, 0 replies; only message in thread
From: Sebastian Pipping (sping) @ 2012-03-15 20:16 UTC (permalink / raw
  To: gentoo-commits

sping       12/03/15 20:16:55

  Added:                gprof2dot-0_p20100216-python3.patch
  Log:
  dev-util/gprof2dot: Python 3.x (bug #341687)
  
  (Portage version: 2.1.10.49/cvs/Linux x86_64)

Revision  Changes    Path
1.1                  dev-util/gprof2dot/files/gprof2dot-0_p20100216-python3.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-util/gprof2dot/files/gprof2dot-0_p20100216-python3.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-util/gprof2dot/files/gprof2dot-0_p20100216-python3.patch?rev=1.1&content-type=text/plain

Index: gprof2dot-0_p20100216-python3.patch
===================================================================
From 6087a16e81d5c41647e05291dd25bb6eac9493eb Mon Sep 17 00:00:00 2001
From: Sebastian Pipping <sebastian@pipping.org>
Date: Fri, 5 Nov 2010 18:10:29 +0100
Subject: [PATCH] Support both Python 2.x and 3.x

---
 gprof2dot.py |  138 ++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 81 insertions(+), 57 deletions(-)

diff --git a/gprof2dot.py b/gprof2dot.py
index bf0aba8..888081f 100755
--- a/gprof2dot.py
+++ b/gprof2dot.py
@@ -32,6 +32,27 @@ import optparse
 import xml.parsers.expat
 
 
+# Python 2.x/3.x compatibility
+if sys.version_info[0] == 3:
+    PYTHON_3 = True
+    def compat_iteritems(x): return x.items()  # No iteritems() in Python 3
+    def compat_itervalues(x): return x.values()  # No itervalues() in Python 3
+    def compat_keys(x): return list(x.keys())  # keys() is a generator in Python 3
+    compat_basestring = str  # No class basestring in Python 3
+
+    CALL_TIMES_FORMAT = "%u\xd7"  # All strings are unicode in Python 3, no u"" marking
+else:
+    PYTHON_3 = False
+    def compat_iteritems(x): return x.iteritems()
+    def compat_itervalues(x): return x.itervalues()
+    def compat_keys(x): return x.keys()
+    compat_basestring = basestring
+
+    # u"" strings not supported in Python 3
+    # By using eval() we don't get a syntax error
+    CALL_TIMES_FORMAT = eval('u"%u\xd7"')
+
+
 try:
     # Debugging helper module
     import debug
@@ -40,7 +61,7 @@ except ImportError:
 
 
 def times(x):
-    return u"%u\xd7" % (x,)
+    return CALL_TIMES_FORMAT % (x,)
 
 def percentage(p):
     return "%.02f%%" % (p*100.0,)
@@ -236,8 +257,8 @@ class Profile(Object):
     def validate(self):
         """Validate the edges."""
 
-        for function in self.functions.itervalues():
-            for callee_id in function.calls.keys():
+        for function in compat_itervalues(self.functions):
+            for callee_id in compat_keys(function.calls):
                 assert function.calls[callee_id].callee_id == callee_id
                 if callee_id not in self.functions:
                     sys.stderr.write('warning: call to undefined function %s from function %s\n' % (str(callee_id), function.name))
@@ -248,11 +269,11 @@ class Profile(Object):
 
         # Apply the Tarjan's algorithm successively until all functions are visited
         visited = set()
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             if function not in visited:
                 self._tarjan(function, 0, [], {}, {}, visited)
         cycles = []
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             if function.cycle is not None and function.cycle not in cycles:
                 cycles.append(function.cycle)
         self.cycles = cycles
@@ -275,7 +296,7 @@ class Profile(Object):
         order += 1
         pos = len(stack)
         stack.append(function)
-        for call in function.calls.itervalues():
+        for call in compat_itervalues(function.calls):
             callee = self.functions[call.callee_id]
             # TODO: use a set to optimize lookup
             if callee not in orders:
@@ -299,10 +320,10 @@ class Profile(Object):
         for cycle in self.cycles:
             cycle_totals[cycle] = 0.0
         function_totals = {}
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             function_totals[function] = 0.0
-        for function in self.functions.itervalues():
-            for call in function.calls.itervalues():
+        for function in compat_itervalues(self.functions):
+            for call in compat_itervalues(function.calls):
                 if call.callee_id != function.id:
                     callee = self.functions[call.callee_id]
                     function_totals[callee] += call[event]
@@ -310,8 +331,8 @@ class Profile(Object):
                         cycle_totals[callee.cycle] += call[event]
 
         # Compute the ratios
-        for function in self.functions.itervalues():
-            for call in function.calls.itervalues():
+        for function in compat_itervalues(self.functions):
+            for call in compat_itervalues(function.calls):
                 assert call.ratio is None
                 if call.callee_id != function.id:
                     callee = self.functions[call.callee_id]
@@ -332,10 +353,10 @@ class Profile(Object):
 
         # Sanity checking
         assert outevent not in self
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             assert outevent not in function
             assert inevent in function
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 assert outevent not in call
                 if call.callee_id != function.id:
                     assert call.ratio is not None
@@ -343,13 +364,13 @@ class Profile(Object):
         # Aggregate the input for each cycle 
         for cycle in self.cycles:
             total = inevent.null()
-            for function in self.functions.itervalues():
+            for function in compat_itervalues(self.functions):
                 total = inevent.aggregate(total, function[inevent])
             self[inevent] = total
 
         # Integrate along the edges
         total = inevent.null()
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             total = inevent.aggregate(total, function[inevent])
             self._integrate_function(function, outevent, inevent)
         self[outevent] = total
@@ -360,7 +381,7 @@ class Profile(Object):
         else:
             if outevent not in function:
                 total = function[inevent]
-                for call in function.calls.itervalues():
+                for call in compat_itervalues(function.calls):
                     if call.callee_id != function.id:
                         total += self._integrate_call(call, outevent, inevent)
                 function[outevent] = total
@@ -381,7 +402,7 @@ class Profile(Object):
             total = inevent.null()
             for member in cycle.functions:
                 subtotal = member[inevent]
-                for call in member.calls.itervalues():
+                for call in compat_itervalues(member.calls):
                     callee = self.functions[call.callee_id]
                     if callee.cycle is not cycle:
                         subtotal += self._integrate_call(call, outevent, inevent)
@@ -390,9 +411,9 @@ class Profile(Object):
             
             # Compute the time propagated to callers of this cycle
             callees = {}
-            for function in self.functions.itervalues():
+            for function in compat_itervalues(self.functions):
                 if function.cycle is not cycle:
-                    for call in function.calls.itervalues():
+                    for call in compat_itervalues(function.calls):
                         callee = self.functions[call.callee_id]
                         if callee.cycle is cycle:
                             try:
@@ -403,7 +424,7 @@ class Profile(Object):
             for member in cycle.functions:
                 member[outevent] = outevent.null()
 
-            for callee, call_ratio in callees.iteritems():
+            for callee, call_ratio in compat_iteritems(callees):
                 ranks = {}
                 call_ratios = {}
                 partials = {}
@@ -418,7 +439,7 @@ class Profile(Object):
     def _rank_cycle_function(self, cycle, function, rank, ranks):
         if function not in ranks or ranks[function] > rank:
             ranks[function] = rank
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 if call.callee_id != function.id:
                     callee = self.functions[call.callee_id]
                     if callee.cycle is cycle:
@@ -427,7 +448,7 @@ class Profile(Object):
     def _call_ratios_cycle(self, cycle, function, ranks, call_ratios, visited):
         if function not in visited:
             visited.add(function)
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 if call.callee_id != function.id:
                     callee = self.functions[call.callee_id]
                     if callee.cycle is cycle:
@@ -438,7 +459,7 @@ class Profile(Object):
     def _integrate_cycle_function(self, cycle, function, partial_ratio, partials, ranks, call_ratios, outevent, inevent):
         if function not in partials:
             partial = partial_ratio*function[inevent]
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 if call.callee_id != function.id:
                     callee = self.functions[call.callee_id]
                     if callee.cycle is not cycle:
@@ -465,7 +486,7 @@ class Profile(Object):
         """Aggregate an event for the whole profile."""
 
         total = event.null()
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             try:
                 total = event.aggregate(total, function[event])
             except UndefinedEvent:
@@ -475,11 +496,11 @@ class Profile(Object):
     def ratio(self, outevent, inevent):
         assert outevent not in self
         assert inevent in self
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             assert outevent not in function
             assert inevent in function
             function[outevent] = ratio(function[inevent], self[inevent])
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 assert outevent not in call
                 if inevent in call:
                     call[outevent] = ratio(call[inevent], self[inevent])
@@ -489,13 +510,13 @@ class Profile(Object):
         """Prune the profile"""
 
         # compute the prune ratios
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             try:
                 function.weight = function[TOTAL_TIME_RATIO]
             except UndefinedEvent:
                 pass
 
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 callee = self.functions[call.callee_id]
 
                 if TOTAL_TIME_RATIO in call:
@@ -509,24 +530,24 @@ class Profile(Object):
                         pass
 
         # prune the nodes
-        for function_id in self.functions.keys():
+        for function_id in compat_keys(self.functions):
             function = self.functions[function_id]
             if function.weight is not None:
                 if function.weight < node_thres:
                     del self.functions[function_id]
 
         # prune the egdes
-        for function in self.functions.itervalues():
-            for callee_id in function.calls.keys():
+        for function in compat_itervalues(self.functions):
+            for callee_id in compat_keys(function.calls):
                 call = function.calls[callee_id]
                 if callee_id not in self.functions or call.weight is not None and call.weight < edge_thres:
                     del function.calls[callee_id]
     
     def dump(self):
-        for function in self.functions.itervalues():
+        for function in compat_itervalues(self.functions):
             sys.stderr.write('Function %s:\n' % (function.name,))
             self._dump_events(function.events)
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 callee = self.functions[call.callee_id]
                 sys.stderr.write('  Call %s:\n' % (callee.name,))
                 self._dump_events(call.events)
@@ -537,7 +558,7 @@ class Profile(Object):
                 sys.stderr.write('  Function %s\n' % (function.name,))
 
     def _dump_events(self, events):
-        for event, value in events.iteritems():
+        for event, value in compat_iteritems(events):
             sys.stderr.write('    %s: %s\n' % (event.name, event.format(value)))
 
 
@@ -695,7 +716,7 @@ class XmlTokenizer:
             self.final = len(data) < size
             try:
                 self.parser.Parse(data, self.final)
-            except xml.parsers.expat.ExpatError, e:
+            except xml.parsers.expat.ExpatError as e:
                 #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS:
                 if e.code == 3:
                     pass
@@ -801,7 +822,7 @@ class GprofParser(Parser):
         """Extract a structure from a match object, while translating the types in the process."""
         attrs = {}
         groupdict = mo.groupdict()
-        for name, value in groupdict.iteritems():
+        for name, value in compat_iteritems(groupdict):
             if value is None:
                 value = None
             elif self._int_re.match(value):
@@ -977,7 +998,7 @@ class GprofParser(Parser):
         for index in self.cycles.iterkeys():
             cycles[index] = Cycle()
 
-        for entry in self.functions.itervalues():
+        for entry in compat_itervalues(self.functions):
             # populate the function
             function = Function(entry.index, entry.name)
             function[TIME] = entry.self
@@ -1019,7 +1040,7 @@ class GprofParser(Parser):
 
             profile[TIME] = profile[TIME] + function[TIME]
 
-        for cycle in cycles.itervalues():
+        for cycle in compat_itervalues(cycles):
             profile.add_cycle(cycle)
 
         # Compute derived events
@@ -1350,7 +1371,7 @@ class OprofileParser(LineParser):
             self.update_subentries_dict(callees_total, callees)
     
     def update_subentries_dict(self, totals, partials):
-        for partial in partials.itervalues():
+        for partial in compat_itervalues(partials):
             try:
                 total = totals[partial.id]
             except KeyError:
@@ -1372,7 +1393,7 @@ class OprofileParser(LineParser):
         
         # populate the profile
         profile[SAMPLES] = 0
-        for _callers, _function, _callees in self.entries.itervalues():
+        for _callers, _function, _callees in compat_itervalues(self.entries):
             function = Function(_function.id, _function.name)
             function[SAMPLES] = _function.samples
             profile.add_function(function)
@@ -1384,10 +1405,10 @@ class OprofileParser(LineParser):
                 function.module = os.path.basename(_function.image)
 
             total_callee_samples = 0
-            for _callee in _callees.itervalues():
+            for _callee in compat_itervalues(_callees):
                 total_callee_samples += _callee.samples
 
-            for _callee in _callees.itervalues():
+            for _callee in compat_itervalues(_callees):
                 if not _callee.self:
                     call = Call(_callee.id)
                     call[SAMPLES2] = _callee.samples
@@ -1548,7 +1569,7 @@ class SysprofParser(XmlParser):
         profile = Profile()
         
         profile[SAMPLES] = 0
-        for id, object in objects.iteritems():
+        for id, object in compat_iteritems(objects):
             # Ignore fake objects (process names, modules, "Everything", "kernel", etc.)
             if object['self'] == 0:
                 continue
@@ -1558,7 +1579,7 @@ class SysprofParser(XmlParser):
             profile.add_function(function)
             profile[SAMPLES] += function[SAMPLES]
 
-        for id, node in nodes.iteritems():
+        for id, node in compat_iteritems(nodes):
             # Ignore fake calls
             if node['self'] == 0:
                 continue
@@ -1672,7 +1693,7 @@ class SharkParser(LineParser):
                 
         profile = Profile()
         profile[SAMPLES] = 0
-        for _function, _callees in self.entries.itervalues():
+        for _function, _callees in compat_itervalues(self.entries):
             function = Function(_function.id, _function.name)
             function[SAMPLES] = _function.samples
             profile.add_function(function)
@@ -1681,7 +1702,7 @@ class SharkParser(LineParser):
             if _function.image:
                 function.module = os.path.basename(_function.image)
 
-            for _callee in _callees.itervalues():
+            for _callee in compat_itervalues(_callees):
                 call = Call(_callee.id)
                 call[SAMPLES] = _callee.samples
                 function.add_call(call)
@@ -1965,7 +1986,8 @@ class PstatsParser:
         self.profile = Profile()
         self.function_ids = {}
 
-    def get_function_name(self, (filename, line, name)):
+    def get_function_name(self, info):
+        filename, line, name = info
         module = os.path.splitext(filename)[0]
         module = os.path.basename(module)
         return "%s:%d:%s" % (module, line, name)
@@ -1986,14 +2008,14 @@ class PstatsParser:
     def parse(self):
         self.profile[TIME] = 0.0
         self.profile[TOTAL_TIME] = self.stats.total_tt
-        for fn, (cc, nc, tt, ct, callers) in self.stats.stats.iteritems():
+        for fn, (cc, nc, tt, ct, callers) in compat_iteritems(self.stats.stats):
             callee = self.get_function(fn)
             callee.called = nc
             callee[TOTAL_TIME] = ct
             callee[TIME] = tt
             self.profile[TIME] += tt
             self.profile[TOTAL_TIME] = max(self.profile[TOTAL_TIME], ct)
-            for fn, value in callers.iteritems():
+            for fn, value in compat_iteritems(callers):
                 caller = self.get_function(fn)
                 call = Call(callee.id)
                 if isinstance(value, tuple):
@@ -2190,7 +2212,7 @@ class DotWriter:
         self.attr('node', fontname=fontname, shape="box", style="filled", fontcolor="white", width=0, height=0)
         self.attr('edge', fontname=fontname)
 
-        for function in profile.functions.itervalues():
+        for function in compat_itervalues(profile.functions):
             labels = []
             if function.process is not None:
                 labels.append(function.process)
@@ -2202,7 +2224,7 @@ class DotWriter:
                     label = event.format(function[event])
                     labels.append(label)
             if function.called is not None:
-                labels.append(u"%u\xd7" % (function.called,))
+                labels.append(CALL_TIMES_FORMAT % (function.called,))
 
             if function.weight is not None:
                 weight = function.weight
@@ -2217,7 +2239,7 @@ class DotWriter:
                 fontsize = "%.2f" % theme.node_fontsize(weight),
             )
 
-            for call in function.calls.itervalues():
+            for call in compat_itervalues(function.calls):
                 callee = profile.functions[call.callee_id]
 
                 labels = []
@@ -2278,7 +2300,7 @@ class DotWriter:
             return
         self.write(' [')
         first = True
-        for name, value in attrs.iteritems():
+        for name, value in compat_iteritems(attrs):
             if first:
                 first = False
             else:
@@ -2291,7 +2313,7 @@ class DotWriter:
     def id(self, id):
         if isinstance(id, (int, float)):
             s = str(id)
-        elif isinstance(id, basestring):
+        elif isinstance(id, compat_basestring):
             if id.isalnum() and not id.startswith('0x'):
                 s = id
             else:
@@ -2300,7 +2322,8 @@ class DotWriter:
             raise TypeError
         self.write(s)
 
-    def color(self, (r, g, b)):
+    def color(self, rgb):
+        r, g, b = rgb
 
         def float2int(f):
             if f <= 0.0:
@@ -2312,7 +2335,8 @@ class DotWriter:
         return "#" + "".join(["%02x" % float2int(c) for c in (r, g, b)])
 
     def escape(self, s):
-        s = s.encode('utf-8')
+        if not PYTHON_3:
+            s = s.encode('utf-8')
         s = s.replace('\\', r'\\')
         s = s.replace('\n', r'\n')
         s = s.replace('\t', r'\t')
@@ -2505,7 +2529,7 @@ class Main:
         profile = self.profile
         profile.prune(self.options.node_thres/100.0, self.options.edge_thres/100.0)
 
-        for function in profile.functions.itervalues():
+        for function in compat_itervalues(profile.functions):
             function.name = self.compress_function_name(function.name)
 
         dot.graph(profile, self.theme)
-- 
1.7.3.2







^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-03-15 20:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-15 20:16 [gentoo-commits] gentoo-x86 commit in dev-util/gprof2dot/files: gprof2dot-0_p20100216-python3.patch Sebastian Pipping (sping)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox