Statistics
| Branch: | Tag: | Revision:

root / lib / outils.py @ f7f03738

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