File: tools.py

package info (click to toggle)
python-pyperform 1.86-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 168 kB
  • sloc: python: 729; makefile: 17
file content (132 lines) | stat: -rw-r--r-- 4,049 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
__author__ = 'calvin'

import sys
import re
from math import log10

if sys.version[0] == '3':
    pass
else:
    range = xrange


classdef_regex = re.compile(r"\S*def .*#!|class .*#!")
tagged_line_regex = re.compile(r".*#!")


def convert_time_units(t):
    """ Convert time in seconds into reasonable time units. """
    order = log10(t)
    if -9 < order < -6:
        time_units = 'ns'
        factor = 1000000000
    elif -6 < order < -3:
        time_units = 'us'
        factor = 1000000
    elif -3 <= order < -1:
        time_units = 'ms'
        factor = 1000.
    elif -1 <= order:
        time_units = 's'
        factor = 1
    return "{:.3f} {}".format(factor * t, time_units)


def globalize_indentation(src):
    """ Strip the indentation level so the code runs in the global scope. """
    lines = src.splitlines()
    indent = len(lines[0]) - len(lines[0].strip(' '))
    func_src = ''
    for ii, l in enumerate(src.splitlines()):
        line = l[indent:]
        func_src += line + '\n'
    return func_src


def remove_decorators(src):
    """ Remove decorators from the source code """
    src = src.strip()
    src_lines = src.splitlines()
    multi_line = False
    n_deleted = 0
    for n in range(len(src_lines)):
        line = src_lines[n - n_deleted].strip()
        if (line.startswith('@') and 'Benchmark' in line) or multi_line:
            del src_lines[n - n_deleted]
            n_deleted += 1
            if line.endswith(')'):
                multi_line = False
            else:
                multi_line = True
    setup_src = '\n'.join(src_lines)
    return setup_src


def get_tagged_imports(fp):
    imports = []
    inside_def = False
    def_lines = []
    def_indent = 0
    with open(fp, 'r') as f:
        lastLine = f.readline()
        for line in f:

            tagged_class_or_def = re.findall(classdef_regex, lastLine)
            tagged_line = re.findall(tagged_line_regex, lastLine)

            # Find the indentation level of the function/class definition and capture all source code lines
            # until we get a line that is the same indentation level (end of function/class definition).
            if tagged_class_or_def or inside_def:
                if tagged_class_or_def and def_lines:
                    imports.append(''.join(def_lines))
                    def_lines = []
                    inside_def = False

                if inside_def:
                    # For lines within the definition
                    indent = len(lastLine) - len(lastLine.lstrip(' '))
                    if indent == def_indent and lastLine != '\n':
                        imports.append(''.join(def_lines))
                        def_lines = []
                        inside_def = False
                        def_indent = 0
                        if tagged_line:
                            imports.append(lastLine)
                    else:
                        if lastLine != '\n':
                            def_lines.append(lastLine)
                else:
                    # For the definition line
                    inside_def = True
                    def_indent = len(lastLine) - len(lastLine.lstrip(' '))
                    def_lines.append(lastLine)
            elif tagged_line:
                imports.append(lastLine)

            lastLine = line

    # Examine the last line
    tagged_line = re.findall(tagged_line_regex, lastLine)
    if inside_def:
        def_lines.append(line)
        imports.append(''.join(def_lines))
    elif tagged_line:
        imports.append(line)

    src = '\n'.join(imports) + '\n'
    return src


def generate_call_statement(func, is_class_method, *args, **kwargs):
    # Create the call statement
    if is_class_method:
        stmt = 'instance.' + func.__name__ + '('
    else:
        stmt = func.__name__ + '('
    for arg in args:
        stmt += arg.__repr__() + ', '
    for kw, val in kwargs.items():
        stmt += '{0}={1}, '.format(kw, val.__repr__())
    stmt = stmt.strip(', ')
    stmt += ')'
    return stmt