MythTV  master
orddict.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 # smolt - Fedora hardware profiler
3 #
4 # Copyright (C) 2011 Raymond Wagner <raymond@wagnerrp.com>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 __doc__="""This is an ordered dictionary implementation to be used to
21 store client data before transmission to the server."""
22 
23 from itertools import imap, izip
24 
25 class OrdDict( dict ):
26  """
27  OrdData.__init__(raw) -> OrdData object
28 
29  A modified dictionary, that maintains the order of items.
30  Data can be accessed as attributes or items.
31  """
32 
33  def __new__(cls, *args, **kwargs):
34  inst = super(OrdDict, cls).__new__(cls, *args, **kwargs)
35  inst.__dict__['_field_order'] = []
36  return inst
37 
38  def __getattr__(self, name):
39  try:
40  return super(OrdDict, self).__getattr__(name)
41  except AttributeError:
42  try:
43  return self[name]
44  except KeyError:
45  raise AttributeError(str(name))
46 
47  def __setattr__(self, name, value):
48  if name in self.__dict__:
49  super(OrdDict, self).__setattr__(name, value)
50  else:
51  self[name] = value
52 
53  def __delattr__(self, name):
54  try:
55  super(OrdDict, self).__delattr__(name)
56  except AttributeError:
57  del self[name]
58 
59  def __setitem__(self, name, value):
60  if name not in self:
61  self._field_order.append(name)
62  super(OrdDict, self).__setitem__(name, value)
63 
64  def __delitem__(self, name):
65  super(OrdDict, self).__delitem__(name)
66  self._field_order.remove(key)
67 
68  def update(self, *data, **kwdata):
69  if len(data) == 1:
70  try:
71  for k,v in data[0].iteritems():
72  self[k] = v
73  except AttributeError:
74  for k,v in iter(data[0]):
75  self[k] = v
76  if len(kwdata):
77  for k,v in kwdata.iteritems():
78  self[k] = v
79 
80  def __iter__(self):
81  return self.iterkeys()
82 
83  def iterkeys(self):
84  return iter(self._field_order)
85 
86  def keys(self):
87  return list(self.iterkeys())
88 
89  def itervalues(self):
90  return imap(self.get, self.iterkeys())
91 
92  def values(self):
93  return list(self.itervalues())
94 
95  def iteritems(self):
96  return izip(self.iterkeys(), self.itervalues())
97 
98  def items(self):
99  return list(self.iteritems())
100 
101  def copy(self):
102  c = self.__class__()
103  for k,v in self.items():
104  try:
105  c[k] = v.copy()
106  except AttributeError:
107  c[k] = v
108  for k,v in self.__dict__.items():
109  try:
110  c[k] = v.copy()
111  except AttributeError:
112  c.__dict__[k] = v
113  return c
114 
115  def clear(self):
116  super(OrdDict, self).clear()
117  self._field_order = []
118 
119 # This sets up a factory for urllib2.Request objects, automatically
120 # providing the base url, user agent, and proxy information.
121 # The object returned is slightly modified, with a shortcut to urlopen.