File: util.py

package info (click to toggle)
cnetworkmanager 0.21.1-1.1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 220 kB
  • ctags: 442
  • sloc: python: 1,252; makefile: 29
file content (163 lines) | stat: -rw-r--r-- 3,717 bytes parent folder | download
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
class NamedNumbers(object):
    """Base for Enum and Flags."""

    def __init__(self, value):
        self.value = value
    def __int__(self):
        """
        >>> n = NamedNumbers(42)

        >>> int(n)
        42
        """
        return self.value

class Enum(NamedNumbers):
    """Enumeration."""

    def __str__(self):
        """
        >>> class Foo(Enum):
        ...    ONE = 1
        ...    TWO = 2

        >>> Foo.ONE
        1

        >>> str(Foo(Foo.TWO))
        'TWO'

        >>> str(Foo(3))
        '3'
        """

        for n, v in self.__class__.__dict__.iteritems():
            if v == self.value:
                return n
        return str(self.value)
    # TODO __repr__

class Flags(NamedNumbers):
    """Bit flags."""

    def __str__(self):
        """
        >>> class MyFlags(Flags):
        ...     NONE = 0x0
        ...     EXECUTE = 0x1
        ...     WRITE = 0x2
        ...     READ = 0x4
    
        >>> str(MyFlags(5))
        'EXECUTE,READ'
    
        >>> str(MyFlags(0))
        'NONE'
    
        >>> str(MyFlags(9)) # doctest: +SKIP
        'EXECUTE,0x8'    
        """

        has = {}
        for n, v in self.__class__.__dict__.iteritems():
            if isinstance(v, int): # FIXME long
                if self.value & v or (self.value == 0 and v == 0):
                    has[v] = n
                    
        names = [has[v] for v in sorted(has.keys())]
        # TODO unknown values?
        return ",".join(names)

class Table(object):
    """Formats a table

    >>> t = Table("A", "Bee", "C")

    >>> t.row("ay", "B", "sea")

    >>> t.row("", "b", "c")

    >>> print t
    A  | Bee | C  
    ---+-----+----
    ay | B   | sea
       | b   | c  

    >>> Table.terse = True

    >>> print t
    ay|B|sea
    |b|c
    """
    # there are trailing spaces in the above non-terse printout

    terse = False
    "No headings and no padding, suitable for parsing."

    def __init__(self, *args):
        "The arguments are column headings."

        self.headings = args
        self.rows = []

    @staticmethod
    def from_items(obj, *items):
        t = Table("Property", "Value")
        for i in items:
            t.row(i, obj[i])
        return t

    @staticmethod
    def from_nested_dict(dd):
        t = Table("Section", "Property", "Value")
        for s, d in dd.iteritems():
            t.row(s, "", "")
            for k, v in d.iteritems():
                if isinstance(v, list):
                    v = ", ".join(v)
                t.row("", k, v)
        return t

    def row(self, *args):
        """The arguments are row items.

        str is applied to them"""
        self.rows.append(map(str,args))

    @staticmethod
    def pad_row(row, col_sizes):
        return map(str.ljust, row, col_sizes)

    def col_widths(self):
        "Returns a list of the column widths."

        # the table of lengths of original items
        lengths = map(lambda cells: map(len, cells), self.rows + [self.headings])
        return reduce(lambda cells1, cells2: map(max, cells1, cells2), lengths)

    def terse_str(self):
        "Formats the table, tersely."

        rs = map("|".join, self.rows)
        return "\n".join(rs)

    def __str__(self):
        "Formats the table."

        if self.terse:
            return self.terse_str()

        cw = self.col_widths()
        def fmt_row(items):
            return " | ".join(self.pad_row(items, cw))
        h = fmt_row(self.headings)
        s = "-+-".join(map(lambda w: "-" * w, cw))
        rs = map(fmt_row, self.rows)
        rs.insert(0, s)
        rs.insert(0, h)
        return "\n".join(rs)


if __name__ == "__main__":
    import doctest
    doctest.testmod()