diff options
Diffstat (limited to 'bitbake/lib/bb/COW.py')
| -rw-r--r-- | bitbake/lib/bb/COW.py | 171 |
1 files changed, 88 insertions, 83 deletions
diff --git a/bitbake/lib/bb/COW.py b/bitbake/lib/bb/COW.py index ca206cf4b4..6917ec378a 100644 --- a/bitbake/lib/bb/COW.py +++ b/bitbake/lib/bb/COW.py | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | # This is a copy on write dictionary and set which abuses classes to try and be nice and fast. | 4 | # This is a copy on write dictionary and set which abuses classes to try and be nice and fast. |
| 5 | # | 5 | # |
| 6 | # Copyright (C) 2006 Tim Amsell | 6 | # Copyright (C) 2006 Tim Amsell |
| 7 | # | 7 | # |
| 8 | # This program is free software; you can redistribute it and/or modify | 8 | # This program is free software; you can redistribute it and/or modify |
| 9 | # it under the terms of the GNU General Public License version 2 as | 9 | # it under the terms of the GNU General Public License version 2 as |
| @@ -18,29 +18,31 @@ | |||
| 18 | # with this program; if not, write to the Free Software Foundation, Inc., | 18 | # with this program; if not, write to the Free Software Foundation, Inc., |
| 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | # | 20 | # |
| 21 | #Please Note: | 21 | #Please Note: |
| 22 | # Be careful when using mutable types (ie Dict and Lists) - operations involving these are SLOW. | 22 | # Be careful when using mutable types (ie Dict and Lists) - operations involving these are SLOW. |
| 23 | # Assign a file to __warn__ to get warnings about slow operations. | 23 | # Assign a file to __warn__ to get warnings about slow operations. |
| 24 | # | 24 | # |
| 25 | 25 | ||
| 26 | from __future__ import print_function | ||
| 26 | import copy | 27 | import copy |
| 27 | import types | 28 | import types |
| 28 | types.ImmutableTypes = tuple([ \ | 29 | ImmutableTypes = ( |
| 29 | types.BooleanType, \ | 30 | types.NoneType, |
| 30 | types.ComplexType, \ | 31 | bool, |
| 31 | types.FloatType, \ | 32 | complex, |
| 32 | types.IntType, \ | 33 | float, |
| 33 | types.LongType, \ | 34 | int, |
| 34 | types.NoneType, \ | 35 | long, |
| 35 | types.TupleType, \ | 36 | tuple, |
| 36 | frozenset] + \ | 37 | frozenset, |
| 37 | list(types.StringTypes)) | 38 | basestring |
| 39 | ) | ||
| 38 | 40 | ||
| 39 | MUTABLE = "__mutable__" | 41 | MUTABLE = "__mutable__" |
| 40 | 42 | ||
| 41 | class COWMeta(type): | 43 | class COWMeta(type): |
| 42 | pass | 44 | pass |
| 43 | 45 | ||
| 44 | class COWDictMeta(COWMeta): | 46 | class COWDictMeta(COWMeta): |
| 45 | __warn__ = False | 47 | __warn__ = False |
| 46 | __hasmutable__ = False | 48 | __hasmutable__ = False |
| @@ -59,12 +61,12 @@ class COWDictMeta(COWMeta): | |||
| 59 | __call__ = cow | 61 | __call__ = cow |
| 60 | 62 | ||
| 61 | def __setitem__(cls, key, value): | 63 | def __setitem__(cls, key, value): |
| 62 | if not isinstance(value, types.ImmutableTypes): | 64 | if not isinstance(value, ImmutableTypes): |
| 63 | if not isinstance(value, COWMeta): | 65 | if not isinstance(value, COWMeta): |
| 64 | cls.__hasmutable__ = True | 66 | cls.__hasmutable__ = True |
| 65 | key += MUTABLE | 67 | key += MUTABLE |
| 66 | setattr(cls, key, value) | 68 | setattr(cls, key, value) |
| 67 | 69 | ||
| 68 | def __getmutable__(cls, key, readonly=False): | 70 | def __getmutable__(cls, key, readonly=False): |
| 69 | nkey = key + MUTABLE | 71 | nkey = key + MUTABLE |
| 70 | try: | 72 | try: |
| @@ -77,10 +79,10 @@ class COWDictMeta(COWMeta): | |||
| 77 | return value | 79 | return value |
| 78 | 80 | ||
| 79 | if not cls.__warn__ is False and not isinstance(value, COWMeta): | 81 | if not cls.__warn__ is False and not isinstance(value, COWMeta): |
| 80 | print >> cls.__warn__, "Warning: Doing a copy because %s is a mutable type." % key | 82 | print("Warning: Doing a copy because %s is a mutable type." % key, file=cls.__warn__) |
| 81 | try: | 83 | try: |
| 82 | value = value.copy() | 84 | value = value.copy() |
| 83 | except AttributeError, e: | 85 | except AttributeError as e: |
| 84 | value = copy.copy(value) | 86 | value = copy.copy(value) |
| 85 | setattr(cls, nkey, value) | 87 | setattr(cls, nkey, value) |
| 86 | return value | 88 | return value |
| @@ -98,13 +100,13 @@ class COWDictMeta(COWMeta): | |||
| 98 | value = getattr(cls, key) | 100 | value = getattr(cls, key) |
| 99 | except AttributeError: | 101 | except AttributeError: |
| 100 | value = cls.__getmutable__(key, readonly) | 102 | value = cls.__getmutable__(key, readonly) |
| 101 | 103 | ||
| 102 | # This is for values which have been deleted | 104 | # This is for values which have been deleted |
| 103 | if value is cls.__marker__: | 105 | if value is cls.__marker__: |
| 104 | raise AttributeError("key %s does not exist." % key) | 106 | raise AttributeError("key %s does not exist." % key) |
| 105 | 107 | ||
| 106 | return value | 108 | return value |
| 107 | except AttributeError, e: | 109 | except AttributeError as e: |
| 108 | if not default is cls.__getmarker__: | 110 | if not default is cls.__getmarker__: |
| 109 | return default | 111 | return default |
| 110 | 112 | ||
| @@ -118,6 +120,9 @@ class COWDictMeta(COWMeta): | |||
| 118 | key += MUTABLE | 120 | key += MUTABLE |
| 119 | delattr(cls, key) | 121 | delattr(cls, key) |
| 120 | 122 | ||
| 123 | def __contains__(cls, key): | ||
| 124 | return cls.has_key(key) | ||
| 125 | |||
| 121 | def has_key(cls, key): | 126 | def has_key(cls, key): |
| 122 | value = cls.__getreadonly__(key, cls.__marker__) | 127 | value = cls.__getreadonly__(key, cls.__marker__) |
| 123 | if value is cls.__marker__: | 128 | if value is cls.__marker__: |
| @@ -127,7 +132,7 @@ class COWDictMeta(COWMeta): | |||
| 127 | def iter(cls, type, readonly=False): | 132 | def iter(cls, type, readonly=False): |
| 128 | for key in dir(cls): | 133 | for key in dir(cls): |
| 129 | if key.startswith("__"): | 134 | if key.startswith("__"): |
| 130 | continue | 135 | continue |
| 131 | 136 | ||
| 132 | if key.endswith(MUTABLE): | 137 | if key.endswith(MUTABLE): |
| 133 | key = key[:-len(MUTABLE)] | 138 | key = key[:-len(MUTABLE)] |
| @@ -153,11 +158,11 @@ class COWDictMeta(COWMeta): | |||
| 153 | return cls.iter("keys") | 158 | return cls.iter("keys") |
| 154 | def itervalues(cls, readonly=False): | 159 | def itervalues(cls, readonly=False): |
| 155 | if not cls.__warn__ is False and cls.__hasmutable__ and readonly is False: | 160 | if not cls.__warn__ is False and cls.__hasmutable__ and readonly is False: |
| 156 | print >> cls.__warn__, "Warning: If you arn't going to change any of the values call with True." | 161 | print("Warning: If you arn't going to change any of the values call with True.", file=cls.__warn__) |
| 157 | return cls.iter("values", readonly) | 162 | return cls.iter("values", readonly) |
| 158 | def iteritems(cls, readonly=False): | 163 | def iteritems(cls, readonly=False): |
| 159 | if not cls.__warn__ is False and cls.__hasmutable__ and readonly is False: | 164 | if not cls.__warn__ is False and cls.__hasmutable__ and readonly is False: |
| 160 | print >> cls.__warn__, "Warning: If you arn't going to change any of the values call with True." | 165 | print("Warning: If you arn't going to change any of the values call with True.", file=cls.__warn__) |
| 161 | return cls.iter("items", readonly) | 166 | return cls.iter("items", readonly) |
| 162 | 167 | ||
| 163 | class COWSetMeta(COWDictMeta): | 168 | class COWSetMeta(COWDictMeta): |
| @@ -176,13 +181,13 @@ class COWSetMeta(COWDictMeta): | |||
| 176 | 181 | ||
| 177 | def remove(cls, value): | 182 | def remove(cls, value): |
| 178 | COWDictMeta.__delitem__(cls, repr(hash(value))) | 183 | COWDictMeta.__delitem__(cls, repr(hash(value))) |
| 179 | 184 | ||
| 180 | def __in__(cls, value): | 185 | def __in__(cls, value): |
| 181 | return COWDictMeta.has_key(repr(hash(value))) | 186 | return COWDictMeta.has_key(repr(hash(value))) |
| 182 | 187 | ||
| 183 | def iterkeys(cls): | 188 | def iterkeys(cls): |
| 184 | raise TypeError("sets don't have keys") | 189 | raise TypeError("sets don't have keys") |
| 185 | 190 | ||
| 186 | def iteritems(cls): | 191 | def iteritems(cls): |
| 187 | raise TypeError("sets don't have 'items'") | 192 | raise TypeError("sets don't have 'items'") |
| 188 | 193 | ||
| @@ -199,120 +204,120 @@ if __name__ == "__main__": | |||
| 199 | import sys | 204 | import sys |
| 200 | COWDictBase.__warn__ = sys.stderr | 205 | COWDictBase.__warn__ = sys.stderr |
| 201 | a = COWDictBase() | 206 | a = COWDictBase() |
| 202 | print "a", a | 207 | print("a", a) |
| 203 | 208 | ||
| 204 | a['a'] = 'a' | 209 | a['a'] = 'a' |
| 205 | a['b'] = 'b' | 210 | a['b'] = 'b' |
| 206 | a['dict'] = {} | 211 | a['dict'] = {} |
| 207 | 212 | ||
| 208 | b = a.copy() | 213 | b = a.copy() |
| 209 | print "b", b | 214 | print("b", b) |
| 210 | b['c'] = 'b' | 215 | b['c'] = 'b' |
| 211 | 216 | ||
| 212 | 217 | print() | |
| 213 | 218 | ||
| 214 | print "a", a | 219 | print("a", a) |
| 215 | for x in a.iteritems(): | 220 | for x in a.iteritems(): |
| 216 | print x | 221 | print(x) |
| 217 | print "--" | 222 | print("--") |
| 218 | print "b", b | 223 | print("b", b) |
| 219 | for x in b.iteritems(): | 224 | for x in b.iteritems(): |
| 220 | print x | 225 | print(x) |
| 221 | 226 | print() | |
| 222 | 227 | ||
| 223 | b['dict']['a'] = 'b' | 228 | b['dict']['a'] = 'b' |
| 224 | b['a'] = 'c' | 229 | b['a'] = 'c' |
| 225 | 230 | ||
| 226 | print "a", a | 231 | print("a", a) |
| 227 | for x in a.iteritems(): | 232 | for x in a.iteritems(): |
| 228 | print x | 233 | print(x) |
| 229 | print "--" | 234 | print("--") |
| 230 | print "b", b | 235 | print("b", b) |
| 231 | for x in b.iteritems(): | 236 | for x in b.iteritems(): |
| 232 | print x | 237 | print(x) |
| 233 | 238 | print() | |
| 234 | 239 | ||
| 235 | try: | 240 | try: |
| 236 | b['dict2'] | 241 | b['dict2'] |
| 237 | except KeyError, e: | 242 | except KeyError as e: |
| 238 | print "Okay!" | 243 | print("Okay!") |
| 239 | 244 | ||
| 240 | a['set'] = COWSetBase() | 245 | a['set'] = COWSetBase() |
| 241 | a['set'].add("o1") | 246 | a['set'].add("o1") |
| 242 | a['set'].add("o1") | 247 | a['set'].add("o1") |
| 243 | a['set'].add("o2") | 248 | a['set'].add("o2") |
| 244 | 249 | ||
| 245 | print "a", a | 250 | print("a", a) |
| 246 | for x in a['set'].itervalues(): | 251 | for x in a['set'].itervalues(): |
| 247 | print x | 252 | print(x) |
| 248 | print "--" | 253 | print("--") |
| 249 | print "b", b | 254 | print("b", b) |
| 250 | for x in b['set'].itervalues(): | 255 | for x in b['set'].itervalues(): |
| 251 | print x | 256 | print(x) |
| 252 | 257 | print() | |
| 253 | 258 | ||
| 254 | b['set'].add('o3') | 259 | b['set'].add('o3') |
| 255 | 260 | ||
| 256 | print "a", a | 261 | print("a", a) |
| 257 | for x in a['set'].itervalues(): | 262 | for x in a['set'].itervalues(): |
| 258 | print x | 263 | print(x) |
| 259 | print "--" | 264 | print("--") |
| 260 | print "b", b | 265 | print("b", b) |
| 261 | for x in b['set'].itervalues(): | 266 | for x in b['set'].itervalues(): |
| 262 | print x | 267 | print(x) |
| 263 | 268 | print() | |
| 264 | 269 | ||
| 265 | a['set2'] = set() | 270 | a['set2'] = set() |
| 266 | a['set2'].add("o1") | 271 | a['set2'].add("o1") |
| 267 | a['set2'].add("o1") | 272 | a['set2'].add("o1") |
| 268 | a['set2'].add("o2") | 273 | a['set2'].add("o2") |
| 269 | 274 | ||
| 270 | print "a", a | 275 | print("a", a) |
| 271 | for x in a.iteritems(): | 276 | for x in a.iteritems(): |
| 272 | print x | 277 | print(x) |
| 273 | print "--" | 278 | print("--") |
| 274 | print "b", b | 279 | print("b", b) |
| 275 | for x in b.iteritems(readonly=True): | 280 | for x in b.iteritems(readonly=True): |
| 276 | print x | 281 | print(x) |
| 277 | 282 | print() | |
| 278 | 283 | ||
| 279 | del b['b'] | 284 | del b['b'] |
| 280 | try: | 285 | try: |
| 281 | print b['b'] | 286 | print(b['b']) |
| 282 | except KeyError: | 287 | except KeyError: |
| 283 | print "Yay! deleted key raises error" | 288 | print("Yay! deleted key raises error") |
| 284 | 289 | ||
| 285 | if b.has_key('b'): | 290 | if b.has_key('b'): |
| 286 | print "Boo!" | 291 | print("Boo!") |
| 287 | else: | 292 | else: |
| 288 | print "Yay - has_key with delete works!" | 293 | print("Yay - has_key with delete works!") |
| 289 | 294 | ||
| 290 | print "a", a | 295 | print("a", a) |
| 291 | for x in a.iteritems(): | 296 | for x in a.iteritems(): |
| 292 | print x | 297 | print(x) |
| 293 | print "--" | 298 | print("--") |
| 294 | print "b", b | 299 | print("b", b) |
| 295 | for x in b.iteritems(readonly=True): | 300 | for x in b.iteritems(readonly=True): |
| 296 | print x | 301 | print(x) |
| 297 | 302 | print() | |
| 298 | 303 | ||
| 299 | b.__revertitem__('b') | 304 | b.__revertitem__('b') |
| 300 | 305 | ||
| 301 | print "a", a | 306 | print("a", a) |
| 302 | for x in a.iteritems(): | 307 | for x in a.iteritems(): |
| 303 | print x | 308 | print(x) |
| 304 | print "--" | 309 | print("--") |
| 305 | print "b", b | 310 | print("b", b) |
| 306 | for x in b.iteritems(readonly=True): | 311 | for x in b.iteritems(readonly=True): |
| 307 | print x | 312 | print(x) |
| 308 | 313 | print() | |
| 309 | 314 | ||
| 310 | b.__revertitem__('dict') | 315 | b.__revertitem__('dict') |
| 311 | print "a", a | 316 | print("a", a) |
| 312 | for x in a.iteritems(): | 317 | for x in a.iteritems(): |
| 313 | print x | 318 | print(x) |
| 314 | print "--" | 319 | print("--") |
| 315 | print "b", b | 320 | print("b", b) |
| 316 | for x in b.iteritems(readonly=True): | 321 | for x in b.iteritems(readonly=True): |
| 317 | print x | 322 | print(x) |
| 318 | 323 | print() | |
