Skip to content
Permalink
Newer
Older
100644 569 lines (485 sloc) 15.9 KB
Sep 5, 2014
1
;(function($B){
2
3
eval($B.InjectBuiltins())
Sep 5, 2014
5
var $ObjectDict = _b_.object.$dict
6
7
// dictionary
8
function $DictClass($keys,$values){
9
this.iter = null
10
this.__class__ = $DictDict
Feb 9, 2015
12
13
var setitem=$DictDict.__setitem__
14
for (var i = 0; i < $keys.length; ++i) {
Feb 9, 2015
15
setitem($keys[i], $values[i])
Sep 5, 2014
19
var $DictDict = {__class__:$B.$type,
20
__name__ : 'dict',
21
$native:true,
22
__dir__:$ObjectDict.__dir__
Sep 5, 2014
23
}
24
25
var $key_iterator = function(d) {
26
this.d = d
27
this.current = 0
28
this.iter = new $item_generator(d)
29
}
30
$key_iterator.prototype.length = function() { return this.iter.length }
31
$key_iterator.prototype.next = function() { return this.iter.next()[0] }
32
33
var $value_iterator = function(d) {
34
this.d = d
35
this.current = 0
36
this.iter = new $item_generator(d)
37
}
38
$value_iterator.prototype.length = function() { return this.iter.length }
39
$value_iterator.prototype.next = function() { return this.iter.next()[1] }
40
41
var $item_generator = function(d) {
42
this.i = 0
43
44
// add numeric, string and object contents to items list
45
_i=[]
46
for (var k in d.$numeric_dict) _i[_i.length]=[parseFloat(k), d.$numeric_dict[k]]
47
for (var k in d.$string_dict) _i[_i.length]=[k, d.$string_dict[k]]
48
for (var k in d.$object_dict) _i[_i.length]=[d.$object_dict[k]]
50
this.items=_i
51
this.length=this.items.length
Feb 9, 2015
53
54
$item_generator.prototype.next = function() {
55
if (this.i < this.items.length) {
56
return this.items[this.i++]
57
}
58
throw _b_.StopIteration("StopIteration")
59
}
60
$item_generator.prototype.as_list = function() {
61
return this.items
62
}
63
64
var $item_iterator = function(d) {
65
this.d = d
66
this.current = 0
67
this.iter = new $item_generator(d)
68
}
69
$item_iterator.prototype.length = function() {return this.iter.items.length }
70
$item_iterator.prototype.next = function() { return _b_.tuple(this.iter.next()) }
71
72
var $copy_dict = function(left, right) {
73
for (var k in right.$string_dict) left.$string_dict[k]=right.$string_dict[k]
74
for (var k in right.$numeric_dict) left.$numeric_dict[k]=right.$numeric_dict[k]
75
for (var k in right.$object_dict) left.$object_dict[k]=right.$object_dict[k]
76
left.length=undefined
77
}
78
79
$iterator_wrapper = function(items,klass){
80
var res = {
81
__class__:klass,
82
__iter__:function(){items.iter.i=0; return res},
83
__len__:function(){return items.length()},
84
__next__:function(){return items.next()},
85
}
86
res.__str__ = res.toString = res.__repr__
87
return res
88
}
89
91
var $dict_keysDict = $B.$iterator_class('dict_keys')
92
93
$DictDict.keys = function(self){
94
if (arguments.length > 1) {
95
var _len=arguments.length - 1
96
var _msg="keys() takes no arguments ("+_len+" given)"
97
throw _b_.TypeError(_msg)
98
}
99
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
100
}
101
102
var $dict_valuesDict = $B.$iterator_class('dict_values')
103
104
$DictDict.values = function(self){
105
if (arguments.length > 1) {
106
var _len=arguments.length - 1
107
var _msg="values() takes no arguments ("+_len+" given)"
108
throw _b_.TypeError(_msg)
109
}
110
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
111
}
112
113
$DictDict.__bool__ = function (self) {return $DictDict.__len__(self) > 0}
Sep 5, 2014
114
115
$DictDict.__contains__ = function(self,item){
116
if(self.$jsobj) return self.$jsobj[item]!==undefined
117
switch(typeof item) {
118
case 'string':
119
return self.$string_dict[item] !==undefined
120
case 'number':
121
return self.$numeric_dict[item] !==undefined
123
return self.$object_dict[_b_.hash(item)] !== undefined
Sep 5, 2014
124
}
125
126
$DictDict.__delitem__ = function(self,arg){
127
self.length=undefined
128
switch(typeof arg) {
129
case 'string':
130
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
131
delete self.$string_dict[arg]
132
if (self.$jsobj) delete self.$jsobj[arg]
133
return
134
case 'number':
135
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
136
delete self.$numeric_dict[arg]
137
if (self.$jsobj) delete self.$jsobj[arg]
138
return
139
}
140
141
// go with defaults
142
var _key = hash(arg)
143
if (self.$object_dict[_key] === undefined) throw KeyError(_b_.str(arg))
144
delete self.$object_dict[_key]
145
146
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
147
}
148
149
$DictDict.__eq__ = function(self,other){
150
if(other===undefined){ // compare self to class "dict"
151
return self===dict
152
}
153
if(!isinstance(other,dict)) return false
154
155
if ($DictDict.__len__(self) != $DictDict.__len__(other)) return false
156
157
var d1 = new $item_generator(self).as_list()
158
159
for (var i=0; i < d1.length; i++) {
160
var key=d1[i][0]
161
if (!$DictDict.__contains__(other, key)) return false
162
var v1=d1[i][1]
163
var v2=$DictDict.__getitem__(other, key)
164
if (!getattr(v1, '__eq__')(v2)) return false
165
}
166
167
return true
Sep 5, 2014
168
}
169
170
$DictDict.__getitem__ = function(self,arg){
171
if(self.$jsobj && self.$jsobj[arg] !== undefined) return self.$jsobj[arg]
172
173
switch(typeof arg) {
174
case 'string':
175
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
176
break
177
case 'number':
178
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
179
}
180
// since the key is more complex use 'default' method of getting item
181
182
var _key = hash(arg)
183
if (self.$object_dict[_key] !== undefined) return self.$object_dict[_key][1]
184
185
if(hasattr(self, '__missing__')) return getattr(self, '__missing__')(arg)
186
Sep 5, 2014
187
throw KeyError(_b_.str(arg))
188
}
189
190
$DictDict.__hash__ = function(self) {
191
if (self === undefined) {
192
return $DictDict.__hashvalue__ || $B.$py_next_hash-- // for hash of dict type (not instance of dict)
193
}
194
throw _b_.TypeError("unhashable type: 'dict'");
195
}
Sep 5, 2014
196
197
$DictDict.__init__ = function(self){
198
var args = []
199
for(var i=1;i<arguments.length;i++){args.push(arguments[i])}
200
$DictDict.clear(self)
201
switch(args.length) {
202
case 0:
203
return
204
case 1:
Sep 5, 2014
205
var obj = args[0]
206
if(Array.isArray(obj)){
207
var i = obj.length
208
var si=$DictDict.__setitem__
209
while(i--) si(self, obj[i][0], obj[i][1])
210
return
211
}else if(isinstance(obj,dict)){
Sep 5, 2014
213
return
214
}
Sep 5, 2014
216
if(obj.__class__===$B.JSObject.$dict){
217
// convert a JSObject into a Python dictionary
218
var si=$DictDict.__setitem__
219
for(var attr in obj.js) si(self,attr,obj.js[attr])
220
221
// Attribute $jsobj is used to update the original JS object
222
// when the dictionary is modified
Sep 5, 2014
224
return
225
}
Sep 5, 2014
228
var $ns=$B.$MakeArgs('dict',args,[],[],'args','kw')
229
var args = $ns['args']
230
var kw = $ns['kw']
Sep 5, 2014
233
if(isinstance(args[0],dict)){
Sep 5, 2014
235
return
236
}
Sep 5, 2014
238
// format dict([(k1,v1),(k2,v2)...])
239
240
if(Array.isArray(args[0])){
241
var src = args[0]
242
var i = src.length
243
var si=$DictDict.__setitem__
244
while(i--) si(self, src[i][0], src[i][1])
245
}else{
246
var iterable = iter(args[0])
247
while(1){
248
try{
249
var elt = next(iterable)
250
var key = getattr(elt,'__getitem__')(0)
251
var value = getattr(elt,'__getitem__')(1)
252
$DictDict.__setitem__(self, key, value)
253
}catch(err){
254
if(err.__name__==='StopIteration'){$B.$pop_exc();break}
255
throw err
256
}
Sep 5, 2014
257
}
258
}
260
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
261
}
262
263
var $dict_iterator = $B.$iterator_class('dict iterator')
264
$DictDict.__iter__ = function(self) {
265
return $DictDict.keys(self)
Sep 5, 2014
266
}
267
268
$DictDict.__len__ = function(self) {
269
if (self.length !== undefined) return self.length
270
var _count=0
272
for (var k in self.$numeric_dict) _count++
273
for (var k in self.$string_dict) _count++
274
for (var k in self.$object_dict) _count++
276
self.length=_count
277
return _count
Sep 5, 2014
279
280
$DictDict.__mro__ = [$DictDict,$ObjectDict]
281
282
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
283
284
$DictDict.__next__ = function(self){
286
self.$iter = new $item_generator(self)
287
}
288
try {
289
return self.$iter.next()
290
} catch (err) {
291
if (err.__name__ !== "StopIteration") { throw err } else { $B.$pop_exc() }
Sep 5, 2014
292
}
293
}
294
295
$DictDict.__repr__ = function(self){
296
if(self===undefined) return "<class 'dict'>"
297
var _objs=[self] // used to elimate recursion
Sep 5, 2014
298
var res=[]
299
var items = new $item_generator(self).as_list()
300
for (var i=0; i < items.length; i++) {
301
var itm = items[i]
Jan 18, 2015
302
if (_objs.indexOf(itm[1]) > -1 && _b_.isinstance(itm[1], [_b_.dict,_b_.list,_b_.set, _b_.tuple])) {
303
var value='?'+_b_.type(itm[1])
304
if(isinstance(itm[1], dict)) value='{...}'
305
res.push(repr(itm[0])+': '+ value)
306
} else {
Jan 18, 2015
307
if (_objs.indexOf(itm[1]) == -1) _objs.push(itm[1])
308
res.push(repr(itm[0])+': '+repr(itm[1]))
309
}
Sep 5, 2014
310
}
311
return '{'+ res.join(', ') +'}'
Sep 5, 2014
312
}
313
314
$DictDict.__setitem__ = function(self,key,value){
315
self.length=undefined
316
switch(typeof key) {
317
case 'string':
318
self.$string_dict[key]=value
319
if(self.$jsobj) self.$jsobj[key]=value
320
return
321
case 'number':
322
self.$numeric_dict[key]=value
323
if(self.$jsobj) self.$jsobj[key]=value
324
return
325
}
326
327
// if we got here the key is more complex, use default method
328
var _key=hash(key)
329
self.$object_dict[_key]=[key, value]
Sep 5, 2014
330
if(self.$jsobj) self.$jsobj[key]=value
331
}
332
333
$DictDict.__str__ = $DictDict.__repr__
334
335
// add "reflected" methods
336
$B.make_rmethods($DictDict)
337
338
$DictDict.clear = function(self){
339
// Remove all items from the dictionary.
340
self.$numeric_dict={}
341
self.$string_dict={}
342
self.$object_dict={}
343
self.length=0
Sep 5, 2014
344
if(self.$jsobj) self.$jsobj={}
345
}
346
347
$DictDict.copy = function(self){
348
// Return a shallow copy of the dictionary
349
var res = _b_.dict()
350
$copy_dict(res, self)
Sep 5, 2014
351
return res
352
}
353
354
$DictDict.get = function(self, key, _default){
355
if (_default === undefined) _default=None
356
switch(typeof key) {
357
case 'string':
358
return self.$string_dict[key] || _default
359
case 'number':
360
return self.$numeric_dict[key] || _default
Sep 5, 2014
361
}
363
var _key=hash(key)
364
if(self.$object_dict[_key] !== undefined) return self.$object_dict[_key][1]
365
if(_default!==undefined) return _default
366
return None
Sep 5, 2014
367
}
368
369
var $dict_itemsDict = $B.$iterator_class('dict_items')
Sep 5, 2014
370
371
$DictDict.items = function(self){
372
if (arguments.length > 1) {
373
var _len=arguments.length - 1
374
var _msg="items() takes no arguments ("+_len+" given)"
375
throw _b_.TypeError(_msg)
376
}
377
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
Sep 5, 2014
378
}
379
380
$DictDict.fromkeys = function(keys,value){
Sep 5, 2014
381
// class method
382
if(value===undefined) value=None
Sep 5, 2014
383
var res = dict()
384
var keys_iter = _b_.iter(keys)
385
while(1){
386
try{
387
var key = _b_.next(keys_iter)
388
$DictDict.__setitem__(res,key,value)
389
}catch(err){
390
if($B.is_exc(err,[_b_.StopIteration])){
391
$B.$pop_exc()
392
return res
393
}
394
throw err
395
}
396
}
397
}
398
399
$DictDict.pop = function(self,key,_default){
400
try{
401
var res = $DictDict.__getitem__(self,key)
402
$DictDict.__delitem__(self,key)
403
return res
404
}catch(err){
405
$B.$pop_exc()
406
if(err.__name__==='KeyError'){
407
if(_default!==undefined) return _default
408
throw err
409
}
410
throw err
411
}
412
}
413
414
$DictDict.popitem = function(self){
415
try{
416
var itm = new $item_iterator(self).next()
417
$DictDict.__delitem__(self,itm[0])
418
return _b_.tuple(itm)
419
}catch(err) {
420
if (err.__name__ == "StopIteration") {
421
$B.$pop_exc()
422
throw KeyError("'popitem(): dictionary is empty'")
423
}
424
}
Sep 5, 2014
425
}
426
427
$DictDict.setdefault = function(self,key,_default){
428
try{return $DictDict.__getitem__(self,key)}
429
catch(err){
430
if(_default===undefined) _default=None
431
$DictDict.__setitem__(self,key,_default)
432
return _default
433
}
434
}
435
436
$DictDict.update = function(self){
437
var params = []
438
for(var i=1;i<arguments.length;i++){params.push(arguments[i])}
Sep 5, 2014
439
var $ns=$B.$MakeArgs('$DictDict.update',params,[],[],'args','kw')
440
var args = $ns['args']
441
if(args.length>0) {
442
var o=args[0]
443
if (isinstance(o,dict)){
444
$copy_dict(self, o)
445
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
446
var _keys=_b_.list(getattr(o, 'keys')())
447
var _ga=getattr(o, '__getitem__')
448
var si=$DictDict.__setitem__
449
for (var i=0; i < _keys.length; i++) {
450
var _value = _ga(_keys[i])
451
si(self, _keys[i], _value)
Sep 5, 2014
454
}
455
var kw = $ns['kw']
456
if (kw !== undefined) $copy_dict(self, kw)
Sep 5, 2014
457
}
458
459
function dict(_args,second){
Sep 5, 2014
460
var res = {__class__:$DictDict}
461
462
if(second===undefined && Array.isArray(_args)){
463
// Form "dict([[key1, value1], [key2,value2], ...])"
464
$DictDict.clear(res)
466
var i = _args.length
467
var si=$DictDict.__setitem__
468
while(i--) si(res, _args[i][0], _args[i][1])
469
470
return res
471
}
472
Sep 5, 2014
473
// apply __init__ with arguments of dict()
474
var args = [res]
475
for(var i=0, _len_i = arguments.length; i < _len_i;i++){args.push(arguments[i])}
Sep 5, 2014
476
$DictDict.__init__.apply(null,args)
477
return res
478
}
Sep 5, 2014
480
dict.__class__ = $B.$factory
481
dict.$dict = $DictDict
482
$DictDict.$factory = dict
483
$DictDict.__new__ = $B.$__new__(dict)
484
485
_b_.dict = dict
487
// following are used for faster access elsewhere
488
$B.$dict_iterator = function(d) { return new $item_generator(d) }
489
$B.$dict_length = $DictDict.__len__
490
$B.$dict_getitem = $DictDict.__getitem__
491
$B.$dict_get = $DictDict.get
492
$B.$dict_set = $DictDict.__setitem__
493
$B.$dict_contains = $DictDict.__contains__
494
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
495
$B.$copy_dict = $copy_dict // copy from right to left
496
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
497
498
// Class used for attribute __dict__ of objects
499
500
$ObjDictDict = {__class__:$B.$type,__name__:'mapping_proxy'}
501
$ObjDictDict.__mro__ = [$ObjDictDict, $DictDict, $ObjectDict]
502
503
$ObjDictDict.__delitem__ = function(self, key){
504
$DictDict.__delitem__(self, key)
505
delete self.$obj[key]
506
}
507
508
$ObjDictDict.__setitem__ = function(self, key, value){
509
$DictDict.__setitem__(self, key, value)
510
self.$obj[key] = value
511
}
512
513
$ObjDictDict.clear = function(self){
514
$DictDict.clear(self)
515
for(var key in self.$obj){delete self.$obj[key]}
516
}
517
518
$ObjDictDict.pop = function(self, key, _default){
519
$DictDict.pop(self, key, _default)
520
delete self.$obj[key]
521
return key
522
}
523
524
$ObjDictDict.popitem = function(self){
525
var res = $DictDict.popitem(self) // tuple
526
var key = res[0]
527
delete self.$obj[key]
528
return res
529
}
530
531
$ObjDictDict.update = function(self){
532
$DictDict.update.apply(null, arguments)
533
// Update attributes of underlying object by iterating on self.items()
534
var it = $DictDict.items(self)
535
while(true){
536
try{
537
var item = next(it)
538
self.$obj[item[0]] = item[1]
539
}catch(err){
540
if($B.is_exc(err,[_b_.StopIteration])){
541
$B.$pop_exc();return
542
}
543
throw err
544
}
545
}
549
// Function called to get attribute "__dict__" of an object
550
if(obj.__class__===$B.$factory){
551
// For classes, use the class dictionary
552
obj = obj.$dict
553
}
554
var res = {__class__:$ObjDictDict,$obj:obj}
555
$DictDict.clear(res)
556
for(var attr in obj){
557
if(attr.charAt(0)!='$'){
558
$DictDict.__setitem__(res, attr, obj[attr])
559
}
560
}
561
return res
562
}
563
obj_dict.$dict = $ObjDictDict
564
obj_dict.__class__ = $B.$factory
565
$ObjDictDict.$factory = obj_dict
566
567
$B.obj_dict = obj_dict
568
Sep 5, 2014
569
})(__BRYTHON__)