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 from builtins import zip
21 from builtins import map
22 from builtins import str
23 __doc__="""This is an ordered dictionary implementation to be used to
24 store client data before transmission to the server."""
25 
26 
27 
28 class OrdDict( dict ):
29  """
30  OrdData.__init__(raw) -> OrdData object
31 
32  A modified dictionary, that maintains the order of items.
33  Data can be accessed as attributes or items.
34  """
35 
36  def __new__(cls, *args, **kwargs):
37  inst = super(OrdDict, cls).__new__(cls, *args, **kwargs)
38  inst.__dict__['_field_order'] = []
39  return inst
40 
41  def __getattr__(self, name):
42  try:
43  return super(OrdDict, self).__getattr__(name)
44  except AttributeError:
45  try:
46  return self[name]
47  except KeyError:
48  raise AttributeError(str(name))
49 
50  def __setattr__(self, name, value):
51  if name in self.__dict__:
52  super(OrdDict, self).__setattr__(name, value)
53  else:
54  self[name] = value
55 
56  def __delattr__(self, name):
57  try:
58  super(OrdDict, self).__delattr__(name)
59  except AttributeError:
60  del self[name]
61 
62  def __setitem__(self, name, value):
63  if name not in self:
64  self._field_order.append(name)
65  super(OrdDict, self).__setitem__(name, value)
66 
67  def __delitem__(self, name):
68  super(OrdDict, self).__delitem__(name)
69  self._field_order.remove(key)
70 
71  def update(self, *data, **kwdata):
72  if len(data) == 1:
73  try:
74  for k,v in data[0].items():
75  self[k] = v
76  except AttributeError:
77  for k,v in iter(data[0]):
78  self[k] = v
79  if len(kwdata):
80  for k,v in kwdata.items():
81  self[k] = v
82 
83  def __iter__(self):
84  return iter(self.keys())
85 
86  def iterkeys(self):
87  return iter(self._field_order)
88 
89  def keys(self):
90  return list(self.iterkeys())
91 
92  def itervalues(self):
93  return map(self.get, iter(self.keys()))
94 
95  def values(self):
96  return list(self.itervalues())
97 
98  def iteritems(self):
99  return zip(iter(self.keys()), iter(self.values()))
100 
101  def items(self):
102  return list(self.iteritems())
103 
104  def copy(self):
105  c = self.__class__()
106  for k,v in list(self.items()):
107  try:
108  c[k] = v.copy()
109  except AttributeError:
110  c[k] = v
111  for k,v in list(self.__dict__.items()):
112  try:
113  c[k] = v.copy()
114  except AttributeError:
115  c.__dict__[k] = v
116  return c
117 
118  def clear(self):
119  super(OrdDict, self).clear()
120  self._field_order = []
121 
122 # This sets up a factory for urllib2.Request objects, automatically
123 # providing the base url, user agent, and proxy information.
124 # The object returned is slightly modified, with a shortcut to urlopen.