root / lib / outils.py @ 28d466dc
History | View | Annotate | Download (4.3 kB)
1 | 32683096 | René Nussbaumer | #
|
---|---|---|---|
2 | 32683096 | René Nussbaumer | #
|
3 | 32683096 | René Nussbaumer | |
4 | 32683096 | René Nussbaumer | # Copyright (C) 2012 Google Inc.
|
5 | 32683096 | René Nussbaumer | #
|
6 | 32683096 | René Nussbaumer | # This program is free software; you can redistribute it and/or modify
|
7 | 32683096 | René Nussbaumer | # it under the terms of the GNU General Public License as published by
|
8 | 32683096 | René Nussbaumer | # the Free Software Foundation; either version 2 of the License, or
|
9 | 32683096 | René Nussbaumer | # (at your option) any later version.
|
10 | 32683096 | René Nussbaumer | #
|
11 | 32683096 | René Nussbaumer | # This program is distributed in the hope that it will be useful, but
|
12 | 32683096 | René Nussbaumer | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 32683096 | René Nussbaumer | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 32683096 | René Nussbaumer | # General Public License for more details.
|
15 | 32683096 | René Nussbaumer | #
|
16 | 32683096 | René Nussbaumer | # You should have received a copy of the GNU General Public License
|
17 | 32683096 | René Nussbaumer | # along with this program; if not, write to the Free Software
|
18 | 32683096 | René Nussbaumer | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | 32683096 | René Nussbaumer | # 02110-1301, USA.
|
20 | 32683096 | René Nussbaumer | |
21 | 32683096 | René Nussbaumer | """Module for object related utils."""
|
22 | 32683096 | René Nussbaumer | |
23 | 32683096 | René Nussbaumer | |
24 | 473ab806 | Michael Hanselmann | #: Supported container types for serialization/de-serialization (must be a
|
25 | 473ab806 | Michael Hanselmann | #: tuple as it's used as a parameter for C{isinstance})
|
26 | 473ab806 | Michael Hanselmann | _SEQUENCE_TYPES = (list, tuple, set, frozenset) |
27 | 473ab806 | Michael Hanselmann | |
28 | 473ab806 | Michael Hanselmann | |
29 | 32683096 | René Nussbaumer | class AutoSlots(type): |
30 | 32683096 | René Nussbaumer | """Meta base class for __slots__ definitions.
|
31 | 32683096 | René Nussbaumer |
|
32 | 32683096 | René Nussbaumer | """
|
33 | 32683096 | René Nussbaumer | def __new__(mcs, name, bases, attrs): |
34 | 32683096 | René Nussbaumer | """Called when a class should be created.
|
35 | 32683096 | René Nussbaumer |
|
36 | 32683096 | René Nussbaumer | @param mcs: The meta class
|
37 | 32683096 | René Nussbaumer | @param name: Name of created class
|
38 | 32683096 | René Nussbaumer | @param bases: Base classes
|
39 | 32683096 | René Nussbaumer | @type attrs: dict
|
40 | 32683096 | René Nussbaumer | @param attrs: Class attributes
|
41 | 32683096 | René Nussbaumer |
|
42 | 32683096 | René Nussbaumer | """
|
43 | 32683096 | René Nussbaumer | assert "__slots__" not in attrs, \ |
44 | 32683096 | René Nussbaumer | "Class '%s' defines __slots__ when it should not" % name
|
45 | 32683096 | René Nussbaumer | |
46 | 32683096 | René Nussbaumer | attrs["__slots__"] = mcs._GetSlots(attrs)
|
47 | 32683096 | René Nussbaumer | |
48 | 32683096 | René Nussbaumer | return type.__new__(mcs, name, bases, attrs) |
49 | 32683096 | René Nussbaumer | |
50 | 32683096 | René Nussbaumer | @classmethod
|
51 | 32683096 | René Nussbaumer | def _GetSlots(mcs, attrs): |
52 | 32683096 | René Nussbaumer | """Used to get the list of defined slots.
|
53 | 32683096 | René Nussbaumer |
|
54 | 32683096 | René Nussbaumer | @param attrs: The attributes of the class
|
55 | 32683096 | René Nussbaumer |
|
56 | 32683096 | René Nussbaumer | """
|
57 | 32683096 | René Nussbaumer | raise NotImplementedError |
58 | 32683096 | René Nussbaumer | |
59 | 32683096 | René Nussbaumer | |
60 | 32683096 | René Nussbaumer | class ValidatedSlots(object): |
61 | 32683096 | René Nussbaumer | """Sets and validates slots.
|
62 | 32683096 | René Nussbaumer |
|
63 | 32683096 | René Nussbaumer | """
|
64 | 32683096 | René Nussbaumer | __slots__ = [] |
65 | 32683096 | René Nussbaumer | |
66 | 32683096 | René Nussbaumer | def __init__(self, **kwargs): |
67 | 32683096 | René Nussbaumer | """Constructor for BaseOpCode.
|
68 | 32683096 | René Nussbaumer |
|
69 | 32683096 | René Nussbaumer | The constructor takes only keyword arguments and will set
|
70 | 32683096 | René Nussbaumer | attributes on this object based on the passed arguments. As such,
|
71 | 32683096 | René Nussbaumer | it means that you should not pass arguments which are not in the
|
72 | 32683096 | René Nussbaumer | __slots__ attribute for this class.
|
73 | 32683096 | René Nussbaumer |
|
74 | 32683096 | René Nussbaumer | """
|
75 | 32683096 | René Nussbaumer | slots = self.GetAllSlots()
|
76 | 32683096 | René Nussbaumer | for (key, value) in kwargs.items(): |
77 | 32683096 | René Nussbaumer | if key not in slots: |
78 | 32683096 | René Nussbaumer | raise TypeError("Object %s doesn't support the parameter '%s'" % |
79 | 32683096 | René Nussbaumer | (self.__class__.__name__, key))
|
80 | 32683096 | René Nussbaumer | setattr(self, key, value) |
81 | 32683096 | René Nussbaumer | |
82 | 32683096 | René Nussbaumer | @classmethod
|
83 | 32683096 | René Nussbaumer | def GetAllSlots(cls): |
84 | 32683096 | René Nussbaumer | """Compute the list of all declared slots for a class.
|
85 | 32683096 | René Nussbaumer |
|
86 | 32683096 | René Nussbaumer | """
|
87 | 32683096 | René Nussbaumer | slots = [] |
88 | 32683096 | René Nussbaumer | for parent in cls.__mro__: |
89 | 32683096 | René Nussbaumer | slots.extend(getattr(parent, "__slots__", [])) |
90 | 32683096 | René Nussbaumer | return slots
|
91 | 32683096 | René Nussbaumer | |
92 | 32683096 | René Nussbaumer | def Validate(self): |
93 | 32683096 | René Nussbaumer | """Validates the slots.
|
94 | 32683096 | René Nussbaumer |
|
95 | 32683096 | René Nussbaumer | This method must be implemented by the child classes.
|
96 | 32683096 | René Nussbaumer |
|
97 | 32683096 | René Nussbaumer | """
|
98 | 32683096 | René Nussbaumer | raise NotImplementedError |
99 | 473ab806 | Michael Hanselmann | |
100 | 473ab806 | Michael Hanselmann | |
101 | 473ab806 | Michael Hanselmann | def ContainerToDicts(container): |
102 | 473ab806 | Michael Hanselmann | """Convert the elements of a container to standard Python types.
|
103 | 473ab806 | Michael Hanselmann |
|
104 | 473ab806 | Michael Hanselmann | This method converts a container with elements to standard Python types. If
|
105 | 473ab806 | Michael Hanselmann | the input container is of the type C{dict}, only its values are touched.
|
106 | 473ab806 | Michael Hanselmann | Those values, as well as all elements of input sequences, must support a
|
107 | 473ab806 | Michael Hanselmann | C{ToDict} method returning a serialized version.
|
108 | 473ab806 | Michael Hanselmann |
|
109 | 473ab806 | Michael Hanselmann | @type container: dict or sequence (see L{_SEQUENCE_TYPES})
|
110 | 473ab806 | Michael Hanselmann |
|
111 | 473ab806 | Michael Hanselmann | """
|
112 | 473ab806 | Michael Hanselmann | if isinstance(container, dict): |
113 | 473ab806 | Michael Hanselmann | ret = dict([(k, v.ToDict()) for k, v in container.items()]) |
114 | 473ab806 | Michael Hanselmann | elif isinstance(container, _SEQUENCE_TYPES): |
115 | 473ab806 | Michael Hanselmann | ret = [elem.ToDict() for elem in container] |
116 | 473ab806 | Michael Hanselmann | else:
|
117 | 473ab806 | Michael Hanselmann | raise TypeError("Unknown container type '%s'" % type(container)) |
118 | 473ab806 | Michael Hanselmann | |
119 | 473ab806 | Michael Hanselmann | return ret
|
120 | 473ab806 | Michael Hanselmann | |
121 | 473ab806 | Michael Hanselmann | |
122 | 473ab806 | Michael Hanselmann | def ContainerFromDicts(source, c_type, e_type): |
123 | 473ab806 | Michael Hanselmann | """Convert a container from standard python types.
|
124 | 473ab806 | Michael Hanselmann |
|
125 | 473ab806 | Michael Hanselmann | This method converts a container with standard Python types to objects. If
|
126 | 473ab806 | Michael Hanselmann | the container is a dict, we don't touch the keys, only the values.
|
127 | 473ab806 | Michael Hanselmann |
|
128 | 473ab806 | Michael Hanselmann | @type source: None, dict or sequence (see L{_SEQUENCE_TYPES})
|
129 | 473ab806 | Michael Hanselmann | @param source: Input data
|
130 | 473ab806 | Michael Hanselmann | @type c_type: type class
|
131 | 473ab806 | Michael Hanselmann | @param c_type: Desired type for returned container
|
132 | 473ab806 | Michael Hanselmann | @type e_type: element type class
|
133 | 473ab806 | Michael Hanselmann | @param e_type: Item type for elements in returned container (must have a
|
134 | 473ab806 | Michael Hanselmann | C{FromDict} class method)
|
135 | 473ab806 | Michael Hanselmann |
|
136 | 473ab806 | Michael Hanselmann | """
|
137 | 473ab806 | Michael Hanselmann | if not isinstance(c_type, type): |
138 | 473ab806 | Michael Hanselmann | raise TypeError("Container type '%s' is not a type" % type(c_type)) |
139 | 473ab806 | Michael Hanselmann | |
140 | 473ab806 | Michael Hanselmann | if source is None: |
141 | 473ab806 | Michael Hanselmann | source = c_type() |
142 | 473ab806 | Michael Hanselmann | |
143 | 473ab806 | Michael Hanselmann | if c_type is dict: |
144 | 473ab806 | Michael Hanselmann | ret = dict([(k, e_type.FromDict(v)) for k, v in source.items()]) |
145 | 473ab806 | Michael Hanselmann | elif c_type in _SEQUENCE_TYPES: |
146 | 473ab806 | Michael Hanselmann | ret = c_type(map(e_type.FromDict, source))
|
147 | 473ab806 | Michael Hanselmann | else:
|
148 | 473ab806 | Michael Hanselmann | raise TypeError("Unknown container type '%s'" % c_type) |
149 | 473ab806 | Michael Hanselmann | |
150 | 473ab806 | Michael Hanselmann | return ret |