Changeset fda1c7b


Ignore:
Timestamp:
11/25/16 01:19:25 (3 months ago)
Author:
Martin Kolman <martin.kolman@…>
Branches:
master
Children:
6261c31
Parents:
337d6cb
git-author:
Martin Kolman <martin.kolman@…> (11/25/16 01:19:25)
git-committer:
Martin Kolman <martin.kolman@…> (11/25/16 01:19:25)
Message:

Some PEP8 for gprof2dot.py

File:
1 edited

Legend:

Unmodified
Added
Removed
  • gprof2dot.py

    r43ccb71 rfda1c7b  
    4343    return u"%u\xd7" % (x,) 
    4444 
     45 
    4546def percentage(p): 
    4647    return "%.02f%%" % (p*100.0,) 
    4748 
     49 
    4850def add(a, b): 
    4951    return a + b 
     52 
    5053 
    5154def equal(a, b): 
     
    5558        return None 
    5659 
     60 
    5761def fail(a, b): 
    5862    assert False 
     
    6064 
    6165tol = 2 ** -23 
     66 
    6267 
    6368def ratio(numerator, denominator): 
     
    8085class UndefinedEvent(Exception): 
    8186    """Raised when attempting to get an event which is undefined.""" 
    82      
     87 
    8388    def __init__(self, event): 
    8489        Exception.__init__(self) 
     
    9297    """Describe a kind of event, and its basic operations.""" 
    9398 
    94     def __init__(self, name, null, aggregator, formatter = str): 
     99    def __init__(self, name, null, aggregator, formatter=str): 
    95100        self.name = name 
    96101        self._null = null 
     
    112117        assert val2 is not None 
    113118        return self._aggregator(val1, val2) 
    114      
     119 
    115120    def format(self, val): 
    116121        """Format an event value.""" 
     
    146151    def __contains__(self, event): 
    147152        return event in self.events 
    148      
     153 
    149154    def __getitem__(self, event): 
    150155        try: 
     
    152157        except KeyError: 
    153158            raise UndefinedEvent(event) 
    154      
     159 
    155160    def __setitem__(self, event, value): 
    156161        if value is None: 
     
    163168class Call(Object): 
    164169    """A call between functions. 
    165      
     170 
    166171    There should be at most one call object for every pair of functions. 
    167172    """ 
     
    187192        self.weight = None 
    188193        self.cycle = None 
    189      
     194 
    190195    def add_call(self, call): 
    191196        if call.callee_id in self.calls: 
     
    262267                for member in cycle.functions: 
    263268                    sys.stderr.write("\tFunction %s\n" % member.name) 
    264      
     269 
    265270    def _tarjan(self, function, order, stack, orders, lowlinks, visited): 
    266271        """Tarjan's strongly connected components algorithm. 
     
    341346                    assert call.ratio is not None 
    342347 
    343         # Aggregate the input for each cycle  
     348        # Aggregate the input for each cycle 
    344349        for cycle in self.cycles: 
    345350            total = inevent.null() 
     
    366371                function[outevent] = total 
    367372            return function[outevent] 
    368      
     373 
    369374    def _integrate_call(self, call, outevent, inevent): 
    370375        assert outevent not in call 
    371376        assert call.ratio is not None 
    372377        callee = self.functions[call.callee_id] 
    373         subtotal = call.ratio *self._integrate_function(callee, outevent, inevent) 
     378        subtotal = call.ratio * self._integrate_function(callee, outevent, inevent) 
    374379        call[outevent] = subtotal 
    375380        return subtotal 
     
    388393                total += subtotal 
    389394            cycle[outevent] = total 
    390              
     395 
    391396            # Compute the time propagated to callers of this cycle 
    392397            callees = {} 
     
    400405                            except KeyError: 
    401406                                callees[callee] = call.ratio 
    402              
     407 
    403408            for member in cycle.functions: 
    404409                member[outevent] = outevent.null() 
     
    501506                if TOTAL_TIME_RATIO in call: 
    502507                    # handle exact cases first 
    503                     call.weight = call[TOTAL_TIME_RATIO]  
     508                    call.weight = call[TOTAL_TIME_RATIO] 
    504509                else: 
    505510                    try: 
    506511                        # make a safe estimate 
    507                         call.weight = min(function[TOTAL_TIME_RATIO], callee[TOTAL_TIME_RATIO])  
     512                        call.weight = min(function[TOTAL_TIME_RATIO], callee[TOTAL_TIME_RATIO]) 
    508513                    except UndefinedEvent: 
    509514                        pass 
     
    522527                if callee_id not in self.functions or call.weight is not None and call.weight < edge_thres: 
    523528                    del function.calls[callee_id] 
    524      
     529 
    525530    def dump(self): 
    526531        for function in self.functions.itervalues(): 
     
    545550    """Masquerade a dictionary with a structure-like behavior.""" 
    546551 
    547     def __init__(self, attrs = None): 
     552    def __init__(self, attrs=None): 
    548553        if attrs is None: 
    549554            attrs = {} 
    550555        self.__dict__['_attrs'] = attrs 
    551      
     556 
    552557    def __getattr__(self, name): 
    553558        try: 
     
    564569    def __repr__(self): 
    565570        return repr(self._attrs) 
    566      
     571 
    567572 
    568573class ParseError(Exception): 
     
    587592        raise NotImplementedError 
    588593 
    589      
     594 
    590595class LineParser(Parser): 
    591596    """Base class for parsers that read line-based formats.""" 
     
    624629class XmlToken: 
    625630 
    626     def __init__(self, type, name_or_data, attrs = None, line = None, column = None): 
     631    def __init__(self, type, name_or_data, attrs=None, line=None, column=None): 
    627632        assert type in (XML_ELEMENT_START, XML_ELEMENT_END, XML_CHARACTER_DATA, XML_EOF) 
    628633        self.type = type 
     
    647652    """Expat based XML tokenizer.""" 
    648653 
    649     def __init__(self, fp, skip_ws = True): 
     654    def __init__(self, fp, skip_ws=True): 
    650655        self.fp = fp 
    651656        self.tokens = [] 
     
    653658        self.final = False 
    654659        self.skip_ws = skip_ws 
    655          
     660 
    656661        self.character_pos = 0, 0 
    657662        self.character_data = '' 
     
    667672        token = XmlToken(XML_ELEMENT_START, name, attributes, line, column) 
    668673        self.tokens.append(token) 
    669      
     674 
    670675    def handle_element_end(self, name): 
    671676        self.finish_character_data() 
     
    681686    def finish_character_data(self): 
    682687        if self.character_data: 
    683             if not self.skip_ws or not self.character_data.isspace():  
     688            if not self.skip_ws or not self.character_data.isspace(): 
    684689                line, column = self.character_pos 
    685690                token = XmlToken(XML_CHARACTER_DATA, self.character_data, None, line, column) 
    686691                self.tokens.append(token) 
    687692            self.character_data = '' 
    688      
     693 
    689694    def next(self): 
    690695        size = 16*1024 
     
    697702                self.parser.Parse(data, self.final) 
    698703            except xml.parsers.expat.ExpatError, e: 
    699                 #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: 
     704                # if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: 
    700705                if e.code == 3: 
    701706                    pass 
     
    731736        self.tokenizer = XmlTokenizer(fp) 
    732737        self.consume() 
    733      
     738 
    734739    def consume(self): 
    735740        self.token = self.tokenizer.next() 
     
    737742    def match_element_start(self, name): 
    738743        return self.token.type == XML_ELEMENT_START and self.token.name_or_data == name 
    739      
     744 
    740745    def match_element_end(self, name): 
    741746        return self.token.type == XML_ELEMENT_END and self.token.name_or_data == name 
     
    751756        self.consume() 
    752757        return attrs 
    753      
     758 
    754759    def element_end(self, name): 
    755760        while self.token.type == XML_CHARACTER_DATA: 
     
    761766        self.consume() 
    762767 
    763     def character_data(self, strip = True): 
     768    def character_data(self, strip=True): 
    764769        data = '' 
    765770        while self.token.type == XML_CHARACTER_DATA: 
     
    829834 
    830835    _cg_primary_re = re.compile( 
    831         r'^\[(?P<index>\d+)\]?' +  
    832         r'\s+(?P<percentage_time>\d+\.\d+)' +  
    833         r'\s+(?P<self>\d+\.\d+)' +  
    834         r'\s+(?P<descendants>\d+\.\d+)' +  
    835         r'\s+(?:(?P<called>\d+)(?:\+(?P<called_self>\d+))?)?' +  
     836        r'^\[(?P<index>\d+)\]?' + 
     837        r'\s+(?P<percentage_time>\d+\.\d+)' + 
     838        r'\s+(?P<self>\d+\.\d+)' + 
     839        r'\s+(?P<descendants>\d+\.\d+)' + 
     840        r'\s+(?:(?P<called>\d+)(?:\+(?P<called_self>\d+))?)?' + 
    836841        r'\s+(?P<name>\S.*?)' + 
    837842        r'(?:\s+<cycle\s(?P<cycle>\d+)>)?' + 
     
    840845 
    841846    _cg_parent_re = re.compile( 
    842         r'^\s+(?P<self>\d+\.\d+)?' +  
    843         r'\s+(?P<descendants>\d+\.\d+)?' +  
    844         r'\s+(?P<called>\d+)(?:/(?P<called_total>\d+))?' +  
     847        r'^\s+(?P<self>\d+\.\d+)?' + 
     848        r'\s+(?P<descendants>\d+\.\d+)?' + 
     849        r'\s+(?P<called>\d+)(?:/(?P<called_total>\d+))?' + 
    845850        r'\s+(?P<name>\S.*?)' + 
    846851        r'(?:\s+<cycle\s(?P<cycle>\d+)>)?' + 
     
    851856 
    852857    _cg_cycle_header_re = re.compile( 
    853         r'^\[(?P<index>\d+)\]?' +  
    854         r'\s+(?P<percentage_time>\d+\.\d+)' +  
    855         r'\s+(?P<self>\d+\.\d+)' +  
    856         r'\s+(?P<descendants>\d+\.\d+)' +  
    857         r'\s+(?:(?P<called>\d+)(?:\+(?P<called_self>\d+))?)?' +  
     858        r'^\[(?P<index>\d+)\]?' + 
     859        r'\s+(?P<percentage_time>\d+\.\d+)' + 
     860        r'\s+(?P<self>\d+\.\d+)' + 
     861        r'\s+(?P<descendants>\d+\.\d+)' + 
     862        r'\s+(?:(?P<called>\d+)(?:\+(?P<called_self>\d+))?)?' + 
    858863        r'\s+<cycle\s(?P<cycle>\d+)\sas\sa\swhole>' + 
    859864        r'\s\[(\d+)\]$' 
     
    861866 
    862867    _cg_cycle_member_re = re.compile( 
    863         r'^\s+(?P<self>\d+\.\d+)?' +  
    864         r'\s+(?P<descendants>\d+\.\d+)?' +  
    865         r'\s+(?P<called>\d+)(?:\+(?P<called_self>\d+))?' +  
     868        r'^\s+(?P<self>\d+\.\d+)?' + 
     869        r'\s+(?P<descendants>\d+\.\d+)?' + 
     870        r'\s+(?P<called>\d+)(?:\+(?P<called_self>\d+))?' + 
    866871        r'\s+(?P<name>\S.*?)' + 
    867872        r'(?:\s+<cycle\s(?P<cycle>\d+)>)?' + 
     
    881886            if line.startswith('['): 
    882887                break 
    883          
     888 
    884889            # read function parent line 
    885890            mo = self._cg_parent_re.match(line) 
     
    902907        while lines: 
    903908            line = lines.pop(0) 
    904              
     909 
    905910            # read function subroutine line 
    906911            mo = self._cg_child_re.match(line) 
     
    912917                child = self.translate(mo) 
    913918                children.append(child) 
    914          
     919 
    915920        function.parents = parents 
    916921        function.children = children 
     
    937942            call = self.translate(mo) 
    938943            cycle.functions.append(call) 
    939          
     944 
    940945        self.cycles[cycle.cycle] = cycle 
    941946 
     
    958963        # process call graph entries 
    959964        entry_lines = [] 
    960         while line != '\014': # form feed 
     965        while line != '\014':  # form feed 
    961966            if line and not line.isspace(): 
    962967                if self._cg_sep_re.match(line): 
     
    964969                    entry_lines = [] 
    965970                else: 
    966                     entry_lines.append(line)             
     971                    entry_lines.append(line) 
    967972            line = self.readline() 
    968      
     973 
    969974    def parse(self): 
    970975        self.parse_cg() 
     
    973978        profile = Profile() 
    974979        profile[TIME] = 0.0 
    975          
     980 
    976981        cycles = {} 
    977982        for index in self.cycles.iterkeys(): 
     
    988993                call[CALLS] = entry.called_self 
    989994                function.called += entry.called_self 
    990              
     995 
    991996            # populate the function calls 
    992997            for child in entry.children: 
    993998                call = Call(child.index) 
    994                  
     999 
    9951000                assert child.called is not None 
    9961001                call[CALLS] = child.called 
    9971002 
    9981003                if child.index not in self.functions: 
    999                     # NOTE: functions that were never called but were discovered by gprof's  
     1004                    # NOTE: functions that were never called but were discovered by gprof's 
    10001005                    # static call graph analysis dont have a call graph entry so we need 
    10011006                    # to add them here 
     
    10131018                    cycle = cycles[entry.cycle] 
    10141019                except KeyError: 
    1015                     sys.stderr.write('warning: <cycle %u as a whole> entry missing\n' % entry.cycle)  
     1020                    sys.stderr.write('warning: <cycle %u as a whole> entry missing\n' % entry.cycle) 
    10161021                    cycle = Cycle() 
    10171022                    cycles[entry.cycle] = cycle 
     
    10351040class CallgrindParser(LineParser): 
    10361041    """Parser for valgrind's callgrind tool. 
    1037      
     1042 
    10381043    See also: 
    10391044    - http://valgrind.org/docs/manual/cl-format.html 
     
    11511156        assert len(values) == self.num_positions + self.num_events 
    11521157 
    1153         positions = values[0 : self.num_positions] 
    1154         events = values[self.num_positions : ] 
     1158        positions = values[0: self.num_positions] 
     1159        events = values[self.num_positions:] 
    11551160 
    11561161        for i in range(self.num_positions): 
     
    11671172 
    11681173        if calls is None: 
    1169             function[SAMPLES] += events[0]  
     1174            function[SAMPLES] += events[0] 
    11701175            self.profile[SAMPLES] += events[0] 
    11711176        else: 
    11721177            callee = self.get_callee() 
    11731178            callee.called += calls 
    1174      
     1179 
    11751180            try: 
    11761181                call = function.calls[callee.id] 
     
    13071312    def get_function(self): 
    13081313        module = self.positions.get('ob', '') 
    1309         filename = self.positions.get('fl', '')  
    1310         function = self.positions.get('fn', '')  
     1314        filename = self.positions.get('fl', '') 
     1315        function = self.positions.get('fn', '') 
    13111316        return self.make_function(module, filename, function) 
    13121317 
    13131318    def get_callee(self): 
    13141319        module = self.positions.get('cob', '') 
    1315         filename = self.positions.get('cfi', '')  
    1316         function = self.positions.get('cfn', '')  
     1320        filename = self.positions.get('cfi', '') 
     1321        function = self.positions.get('cfn', '') 
    13171322        return self.make_function(module, filename, function) 
    13181323 
     
    13201325class OprofileParser(LineParser): 
    13211326    """Parser for oprofile callgraph output. 
    1322      
     1327 
    13231328    See also: 
    13241329    - http://oprofile.sourceforge.net/doc/opreport.html#opreport-callgraph 
     
    13491354            function_total.samples += function.samples 
    13501355            self.update_subentries_dict(callees_total, callees) 
    1351      
     1356 
    13521357    def update_subentries_dict(self, totals, partials): 
    13531358        for partial in partials.itervalues(): 
     
    13581363            else: 
    13591364                total.samples += partial.samples 
    1360          
     1365 
    13611366    def parse(self): 
    13621367        # read lookahead 
     
    13701375 
    13711376        reverse_call_samples = {} 
    1372          
     1377 
    13731378        # populate the profile 
    13741379        profile[SAMPLES] = 0 
     
    13931398                    call[SAMPLES2] = _callee.samples 
    13941399                    function.add_call(call) 
    1395                  
     1400 
    13961401        # compute derived data 
    13971402        profile.validate() 
     
    14791484        line = self.lookahead() 
    14801485        return not line[:1].isspace() 
    1481      
     1486 
    14821487    def match_secondary(self): 
    14831488        line = self.lookahead() 
     
    15471552    def build_profile(self, objects, nodes): 
    15481553        profile = Profile() 
    1549          
     1554 
    15501555        profile[SAMPLES] = 0 
    15511556        for id, object in objects.items(): 
     
    16171622            entry = self.entries[function.id] 
    16181623        except KeyError: 
    1619             self.entries[function.id] = (function, { }) 
     1624            self.entries[function.id] = (function, {}) 
    16201625        else: 
    16211626            function_total, callees_total = entry 
    16221627            function_total.samples += function.samples 
    1623      
     1628 
    16241629    def add_callee(self, function, callee): 
    16251630        func, callees = self.entries[function.id] 
     
    16301635        else: 
    16311636            entry.samples += callee.samples 
    1632          
     1637 
    16331638    def parse(self): 
    16341639        self.readline() 
     
    16681673            if prefix > 0: 
    16691674                self.add_callee(self.stack[prefix - 1], entry) 
    1670                  
     1675 
    16711676            self.add_entry(entry) 
    1672                  
     1677 
    16731678        profile = Profile() 
    16741679        profile[SAMPLES] = 0 
     
    16861691                call[SAMPLES] = _callee.samples 
    16871692                function.add_call(call) 
    1688                  
     1693 
    16891694        # compute derived data 
    16901695        profile.validate() 
     
    17161721 
    17171722        self.profile = Profile() 
    1718      
     1723 
    17191724    _symbol_re = re.compile( 
    1720         r'^(?P<id>\w+)' +  
    1721         r'\s+"(?P<module>[^"]*)"' +  
    1722         r'\s+"(?P<procname>[^"]*)"' +  
    1723         r'\s+"(?P<sourcefile>[^"]*)"' +  
     1725        r'^(?P<id>\w+)' + 
     1726        r'\s+"(?P<module>[^"]*)"' + 
     1727        r'\s+"(?P<procname>[^"]*)"' + 
     1728        r'\s+"(?P<sourcefile>[^"]*)"' + 
    17241729        r'\s+(?P<sourceline>\d+)$' 
    17251730    ) 
     
    17311736            if mo: 
    17321737                symbol_id, module, procname, sourcefile, sourceline = mo.groups() 
    1733      
     1738 
    17341739                function_id = ':'.join([module, procname]) 
    17351740 
     
    17561761            callee[SAMPLES] += samples 
    17571762            self.profile[SAMPLES] += samples 
    1758              
     1763 
    17591764            for caller in callstack[1:]: 
    17601765                try: 
     
    18241829        results = self.parse_results() 
    18251830        self.element_end('AQtime_Results') 
    1826         return self.build_profile(results)  
     1831        return self.build_profile(results) 
    18271832 
    18281833    def parse_headers(self): 
     
    19281933        profile.ratio(TOTAL_TIME_RATIO, TOTAL_TIME) 
    19291934        return profile 
    1930      
     1935 
    19311936    def build_function(self, fields): 
    19321937        function = Function(self.build_id(fields), self.build_name(fields)) 
     
    20152020 
    20162021                caller.add_call(call) 
    2017         #self.stats.print_stats() 
    2018         #self.stats.print_callees() 
     2022        # self.stats.print_stats() 
     2023        # self.stats.print_callees() 
    20192024 
    20202025        # Compute derived events 
     
    20852090    def color(self, weight): 
    20862091        weight = min(max(weight, 0.0), 1.0) 
    2087      
     2092 
    20882093        hmin, smin, lmin = self.mincolor 
    20892094        hmax, smax, lmax = self.maxcolor 
    2090          
     2095 
    20912096        if self.skew < 0: 
    20922097            raise ValueError("Skew must be greater than 0") 
     
    21462151 
    21472152TEMPERATURE_COLORMAP = Theme( 
    2148     mincolor = (2.0/3.0, 0.80, 0.25), # dark blue 
    2149     maxcolor = (0.0, 1.0, 0.5), # satured red 
    2150     gamma = 1.0 
     2153    mincolor=(2.0/3.0, 0.80, 0.25), # dark blue 
     2154    maxcolor=(0.0, 1.0, 0.5), # satured red 
     2155    gamma=1.0 
    21512156) 
    21522157 
    21532158PINK_COLORMAP = Theme( 
    2154     mincolor = (0.0, 1.0, 0.90), # pink 
    2155     maxcolor = (0.0, 1.0, 0.5), # satured red 
     2159    mincolor=(0.0, 1.0, 0.90), # pink 
     2160    maxcolor=(0.0, 1.0, 0.5), # satured red 
    21562161) 
    21572162 
    21582163GRAY_COLORMAP = Theme( 
    2159     mincolor = (0.0, 0.0, 0.85), # light gray 
    2160     maxcolor = (0.0, 0.0, 0.0), # black 
     2164    mincolor=(0.0, 0.0, 0.85), # light gray 
     2165    maxcolor=(0.0, 0.0, 0.0), # black 
    21612166) 
    21622167 
    21632168BW_COLORMAP = Theme( 
    2164     minfontsize = 8.0, 
    2165     maxfontsize = 24.0, 
    2166     mincolor = (0.0, 0.0, 0.0), # black 
    2167     maxcolor = (0.0, 0.0, 0.0), # black 
    2168     minpenwidth = 0.1, 
    2169     maxpenwidth = 8.0, 
     2169    minfontsize=8.0, 
     2170    maxfontsize=24.0, 
     2171    mincolor=(0.0, 0.0, 0.0), # black 
     2172    maxcolor=(0.0, 0.0, 0.0), # black 
     2173    minpenwidth=0.1, 
     2174    maxpenwidth=8.0, 
    21702175) 
    21712176 
     
    22112216 
    22122217            label = '\n'.join(labels) 
    2213             self.node(function.id,  
    2214                 label = label,  
    2215                 color = self.color(theme.node_bgcolor(weight)),  
    2216                 fontcolor = self.color(theme.node_fgcolor(weight)),  
    2217                 fontsize = "%.2f" % theme.node_fontsize(weight), 
    2218             ) 
     2218            self.node(function.id, 
     2219                      label=label, 
     2220                      color=self.color(theme.node_bgcolor(weight)), 
     2221                      fontcolor=self.color(theme.node_fgcolor(weight)), 
     2222                      fontsize="%.2f" % theme.node_fontsize(weight), 
     2223                      ) 
    22192224 
    22202225            for call in function.calls.itervalues(): 
     
    22362241                label = '\n'.join(labels) 
    22372242 
    2238                 self.edge(function.id, call.callee_id,  
    2239                     label = label,  
    2240                     color = self.color(theme.edge_color(weight)),  
    2241                     fontcolor = self.color(theme.edge_color(weight)), 
    2242                     fontsize = "%.2f" % theme.edge_fontsize(weight),  
    2243                     penwidth = "%.2f" % theme.edge_penwidth(weight),  
    2244                     labeldistance = "%.2f" % theme.edge_penwidth(weight),  
    2245                     arrowsize = "%.2f" % theme.edge_arrowsize(weight), 
    2246                 ) 
     2243                self.edge(function.id, call.callee_id, 
     2244                          label=label, 
     2245                          color=self.color(theme.edge_color(weight)), 
     2246                          fontcolor=self.color(theme.edge_color(weight)), 
     2247                          fontsize="%.2f" % theme.edge_fontsize(weight), 
     2248                          penwidth="%.2f" % theme.edge_penwidth(weight), 
     2249                          labeldistance="%.2f" % theme.edge_penwidth(weight), 
     2250                          arrowsize="%.2f" % theme.edge_arrowsize(weight), 
     2251                          ) 
    22472252 
    22482253        self.end_graph() 
     
    24392444 
    24402445        self.profile = parser.parse() 
    2441          
     2446 
    24422447        if self.options.output is None: 
    24432448            self.output = sys.stdout 
     
    24842489        name = name.replace(", ", ",") 
    24852490        name = name.replace("> >", ">>") 
    2486         name = name.replace("> >", ">>") # catch consecutive 
     2491        name = name.replace("> >", ">>")  # catch consecutive 
    24872492 
    24882493        return name 
Note: See TracChangeset for help on using the changeset viewer.