Skip to content
Permalink
Newer
Older
100644 766 lines (649 sloc) 21.1 KB
Sep 5, 2014
1
;(function($B){
2
3
eval($B.InjectBuiltins())
5
var $ObjectDict = _b_.object.$dict,
6
str_hash = _b_.str.$dict.__hash__,
7
$N = _b_.None
Sep 5, 2014
8
9
// dictionary
10
function $DictClass($keys,$values){
11
this.iter = null
12
this.__class__ = $DictDict
Feb 9, 2015
14
15
var setitem=$DictDict.__setitem__
16
var i=$keys.length
17
while(i--) setitem($keys[i], $values[i])
Sep 5, 2014
20
var $DictDict = {__class__:$B.$type,
21
__name__ : 'dict',
22
$native:true,
23
__dir__:$ObjectDict.__dir__
Sep 5, 2014
24
}
25
26
var $key_iterator = function(d) {
27
this.d = d
28
this.current = 0
29
this.iter = new $item_generator(d)
30
}
31
$key_iterator.prototype.length = function() { return this.iter.length }
32
$key_iterator.prototype.next = function() { return this.iter.next()[0] }
33
34
var $value_iterator = function(d) {
35
this.d = d
36
this.current = 0
37
this.iter = new $item_generator(d)
38
}
39
$value_iterator.prototype.length = function() { return this.iter.length }
40
$value_iterator.prototype.next = function() { return this.iter.next()[1] }
41
42
var $item_generator = function(d) {
44
this.i = 0
46
if(d.$jsobj){
47
this.items = []
49
if(attr.charAt(0)!='$'){
50
val = d.$jsobj[attr];
51
if (val === undefined || val === null) this.items.push([attr,$N])
52
else this.items.push([attr,val])
53
}
55
this.length=this.items.length;
56
return
57
}
59
var items=[]
62
items[pos++]=[parseFloat(k), d.$numeric_dict[k]]
65
for (var k in d.$string_dict) {items[pos++]=[k, d.$string_dict[k]]}
67
for (var k in d.$object_dict) {items[pos++] = d.$object_dict[k]}
68
69
this.items=items
70
this.length=items.length
Feb 9, 2015
72
73
$item_generator.prototype.next = function() {
74
if (this.i < this.items.length) {
75
return this.items[this.i++]
76
}
77
throw _b_.StopIteration("StopIteration")
78
}
79
$item_generator.prototype.as_list = function() {
80
return this.items
81
}
82
83
var $item_iterator = function(d) {
84
this.d = d
85
this.current = 0
86
this.iter = new $item_generator(d)
87
}
88
$item_iterator.prototype.length = function() {return this.iter.items.length }
89
$item_iterator.prototype.next = function() { return _b_.tuple(this.iter.next()) }
90
91
var $copy_dict = function(left, right) {
92
var _l=new $item_generator(right).as_list()
93
var si=$DictDict.__setitem__
94
var i=_l.length
95
while(i--) si(left, _l[i][0], _l[i][1])
98
function toSet(items){
99
// Build a set from the iteration on items
100
var res = []
101
while(true){
102
try{res.push(items.next())}
103
catch(err){break}
104
}
105
return _b_.set(res)
106
}
107
108
var $iterator_wrapper = function(items,klass){
109
var res = {
110
__class__:klass,
111
__eq__:function(other){
112
// compare set of items to other
113
return getattr(toSet(items), "__eq__")(other)
114
},
115
__iter__:function(){items.iter.i=0; return res},
116
__len__:function(){return items.length()},
117
__next__:function(){
118
return items.next()
119
},
120
__repr__:function(){
121
var s = []
122
for(var i=0, len=items.length(); i<len; i++){
123
s.push(_b_.repr(items.next()))
124
}
125
return klass.__name__+'(['+ s.join(',') + '])'
126
},
127
}
128
res.__str__ = res.toString = res.__repr__
129
return res
130
}
131
132
$DictDict.__bool__ = function () {
Nov 21, 2015
133
var $=$B.args('__bool__',1,{self:null},['self'],arguments,{},null,null)
134
return $DictDict.__len__($.self) > 0
137
$DictDict.__contains__ = function(){
Nov 21, 2015
138
139
var $ = $B.args('__contains__', 2, {self:null, item:null},
140
['self', 'item'], arguments, {}, null, null),
141
self=$.self, item=$.item
Nov 21, 2015
142
Sep 5, 2014
143
if(self.$jsobj) return self.$jsobj[item]!==undefined
Nov 21, 2015
144
145
switch(typeof item) {
146
case 'string':
147
return self.$string_dict[item] !==undefined
148
case 'number':
149
return self.$numeric_dict[item] !==undefined
151
152
var _key=hash(item)
153
if (self.$str_hash[_key]!==undefined &&
154
_b_.getattr(item,'__eq__')(self.$str_hash[_key])){return true}
155
if (self.$numeric_dict[_key]!==undefined &&
156
_b_.getattr(item,'__eq__')(_key)){return true}
157
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
158
// If the key is an object, its hash must be in the dict keys but the
159
// key itself must compare equal to the key associated with the hash
160
// For instance :
161
//
162
// class X:
163
// def __hash__(self): return hash('u')
164
//
Nov 21, 2015
165
// a = {'u': 'a', X(): 'b'}
166
// assert set(a.values())=={'a', 'b'}
167
// assert not X() in a
169
var _eq = getattr(item, '__eq__')
Nov 21, 2015
170
if(_eq(self.$object_dict[_key][0])){return true}
171
}
172
return false
Sep 5, 2014
173
}
174
Nov 21, 2015
175
$DictDict.__delitem__ = function(){
176
177
var $ = $B.args('__eq__', 2, {self:null, arg:null},
178
['self', 'arg'], arguments, {}, null, null),
179
self=$.self, arg=$.arg
180
181
if(self.$jsobj){
182
if(self.$jsobj[arg]===undefined){throw KeyError(arg)}
183
delete self.$jsobj[arg]
186
switch(typeof arg) {
187
case 'string':
188
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
189
delete self.$string_dict[arg]
190
delete self.$str_hash[str_hash(arg)]
192
case 'number':
193
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
194
delete self.$numeric_dict[arg]
197
// go with defaults
199
var _key=hash(arg)
201
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
202
delete self.$object_dict[_key]
204
205
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
207
}
208
Nov 21, 2015
209
$DictDict.__eq__ = function(){
210
var $ = $B.args('__eq__', 2, {self:null, other:null},
211
['self', 'other'], arguments, {}, null, null),
212
self=$.self, other=$.other
213
214
if(!isinstance(other,dict)) return false
215
216
if(self.$jsobj){self=self.$to_dict()}
217
if(other.$jsobj){other=other.$to_dict()}
218
219
if ($DictDict.__len__(self) != $DictDict.__len__(other)){return false}
Nov 21, 2015
221
if((self.$numeric_dict.length!=other.$numeric_dict.length) ||
222
(self.$string_dict.length!=other.$string_dict.length) ||
223
(self.$object_dict.length!=other.$object_dict.length)){
224
return false
Nov 21, 2015
226
for(var k in self.$numeric_dict){
227
if(!_b_.getattr(other.$numeric_dict[k],'__eq__')(self.$numeric_dict[k])){
228
return false
229
}
230
}
231
for(var k in self.$string_dict){
232
if(!_b_.getattr(other.$string_dict[k],'__eq__')(self.$string_dict[k])){
233
return false
234
}
235
}
236
for(var k in self.$object_dict){
237
if(!_b_.getattr(other.$object_dict[k][1],'__eq__')(self.$object_dict[k][1])){
238
return false
239
}
240
}
Nov 21, 2015
243
Sep 5, 2014
244
}
245
Nov 21, 2015
246
$DictDict.__getitem__ = function(){
247
var $ = $B.args('__getitem__', 2, {self:null, arg:null},
248
['self', 'arg'], arguments, {}, null, null),
249
self=$.self, arg=$.arg
250
251
if(self.$jsobj){
252
if(self.$jsobj[arg]===undefined || self.$jsobj[arg]===null){return $N}
253
return self.$jsobj[arg]
254
}
255
256
257
switch(typeof arg) {
258
case 'string':
259
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
260
break
261
case 'number':
262
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
265
// since the key is more complex use 'default' method of getting item
266
267
var _key = _b_.hash(arg),
268
_eq = _b_.getattr(arg, '__eq__')
269
270
var sk = self.$str_hash[_key]
271
if (sk!==undefined && _eq(sk)){
272
return self.$string_dict[sk]
273
}
274
if (self.$numeric_dict[_key]!==undefined && _eq(_key)){
275
return self.$numeric_dict[_key]
277
278
var obj_ref = self.$object_dict[_key]
279
if(obj_ref!==undefined){
280
// An object with the same hash is already stored
281
// Lookup should fail if equality raises an exception
282
_eq(self.$object_dict[_key][0])
Nov 21, 2015
283
return self.$object_dict[_key][1]
285
if(self.__class__!==$DictDict){
286
try{
287
var missing_method = getattr(self.__class__.$factory, '__missing__')
288
return missing_method(self, arg)
289
}catch(err){}
290
}
Sep 5, 2014
291
throw KeyError(_b_.str(arg))
292
}
293
294
$DictDict.__hash__ = None
Sep 5, 2014
295
296
$DictDict.__init__ = function(self){
297
var args = [], pos=0
298
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
300
switch(args.length) {
301
case 0:
302
return
303
case 1:
Sep 5, 2014
304
var obj = args[0]
305
if(Array.isArray(obj)){
306
var i = obj.length
307
var si = $DictDict.__setitem__
308
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
310
}else if(obj.$nat===undefined && isinstance(obj,dict)){
Sep 5, 2014
313
}
Sep 5, 2014
315
if(obj.__class__===$B.JSObject.$dict){
316
// convert a JSObject into a Python dictionary
318
// Attribute $jsobj is used to update the original JS object
319
// when the dictionary is modified
Sep 5, 2014
322
}
325
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
326
var args = $ns['args']
327
var kw = $ns['kw']
Sep 5, 2014
330
if(isinstance(args[0],dict)){
Sep 5, 2014
333
}
Sep 5, 2014
335
// format dict([(k1,v1),(k2,v2)...])
337
if(Array.isArray(args[0])){
338
var src = args[0]
340
var si=$DictDict.__setitem__
341
while(i-->0) si(self, src[i-1][0], src[i-1][1])
343
var iterable = $B.$iter(args[0])
344
while(1){
345
try{
346
var elt = next(iterable)
347
var key = getattr(elt,'__getitem__')(0)
348
var value = getattr(elt,'__getitem__')(1)
349
$DictDict.__setitem__(self, key, value)
350
}catch(err){
351
if(err.__name__==='StopIteration'){break}
Sep 5, 2014
354
}
355
}
357
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
359
}
360
361
var $dict_iterator = $B.$iterator_class('dict iterator')
362
$DictDict.__iter__ = function(self) {
363
return $DictDict.keys(self)
Sep 5, 2014
364
}
365
366
$DictDict.__len__ = function(self) {
367
var _count=0
369
if(self.$jsobj){
370
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
371
return _count
372
}
374
for (var k in self.$numeric_dict) _count++
375
for (var k in self.$string_dict) _count++
376
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
378
return _count
Sep 5, 2014
380
381
$DictDict.__mro__ = [$ObjectDict]
Sep 5, 2014
382
383
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
384
385
$DictDict.__next__ = function(self){
387
self.$iter = new $item_generator(self)
388
}
389
try {
390
return self.$iter.next()
391
} catch (err) {
392
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
393
}
394
}
395
396
$DictDict.__repr__ = function(self){
397
if(self===undefined) return "<class 'dict'>"
398
if(self.$jsobj){ // wrapper around Javascript object
399
return $DictDict.__repr__(self.$to_dict())
400
/*
401
var res = []
402
for(var attr in self.$jsobj){
403
if(attr.charAt(0)=='$' || attr=='__class__'){continue}
Nov 4, 2015
404
else{
405
try{
406
res.push("'"+attr+"': "+_b_.repr(self.$jsobj[attr]))
407
}catch(err){
408
// FIX ME
409
}
410
}
411
}
412
return '{'+res.join(', ')+'}'
413
*/
415
var res=[],
416
pos=0,
417
items = new $item_generator(self).as_list()
418
for (var i=0; i < items.length; i++) {
419
var itm = items[i]
420
if(itm[1]===self){res[pos++]=repr(itm[0])+': {...}'}
421
else{res[pos++]=repr(itm[0])+': '+repr(itm[1])}
Sep 5, 2014
422
}
423
return '{'+ res.join(', ') +'}'
Sep 5, 2014
424
}
425
426
$DictDict.__setitem__ = function(self,key,value){
Nov 21, 2015
428
var $ = $B.args('__setitem__', 3, {self:null, key:null, value:null},
429
['self', 'key', 'value'], arguments, {}, null, null),
430
self=$.self, key=$.key, value=$.value
431
432
if(self.$jsobj){
433
if (value === $N) self.$jsobj[key] = undefined;
434
else self.$jsobj[key]=value;
435
return
436
}
438
switch(typeof key) {
439
case 'string':
440
self.$string_dict[key]=value
441
self.$str_hash[str_hash(key)]=key
443
case 'number':
444
self.$numeric_dict[key]=value
448
// if we got here the key is more complex, use default method
450
var _key=hash(key)
451
var _eq=getattr(key, '__eq__')
453
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
454
self.$numeric_dict[_key] = value
456
}
457
var sk = self.$str_hash[_key]
458
if(sk!==undefined && _eq(sk)){
459
self.$string_dict[sk] = value
461
}
462
463
var obj_ref = self.$object_dict[_key]
464
if(obj_ref!==undefined){
465
// An object with the same hash is already stored
466
// Lookup should fail if equality raises an exception
467
_eq(self.$object_dict[_key][0])
468
}
469
self.$object_dict[_key] = [key, value]
Sep 5, 2014
471
}
472
473
$DictDict.__str__ = $DictDict.__repr__
474
475
// add "reflected" methods
476
$B.make_rmethods($DictDict)
477
478
$DictDict.clear = function(){
Sep 5, 2014
479
// Remove all items from the dictionary.
480
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
481
self = $.self
483
self.$numeric_dict={}
484
self.$string_dict={}
485
self.$str_hash={}
486
self.$object_dict={}
Sep 5, 2014
488
if(self.$jsobj) self.$jsobj={}
Sep 5, 2014
490
}
491
492
$DictDict.copy = function(self){
493
// Return a shallow copy of the dictionary
494
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
495
self = $.self,
496
res = _b_.dict()
Sep 5, 2014
498
return res
499
}
500
Nov 21, 2015
501
$DictDict.fromkeys = function(){
502
503
var $ = $B.args('fromkeys', 3, {cls:null, keys:null, value:null},
504
['cls', 'keys', 'value'], arguments, {value:_b_.None}, null, null),
Nov 21, 2015
505
keys=$.keys, value=$.value
Sep 5, 2014
507
// class method
508
var klass = $.cls,
509
res = klass(),
Sep 5, 2014
512
while(1){
513
try{
514
var key = _b_.next(keys_iter)
515
if(klass===dict){$DictDict.__setitem__(res, key, value)}
516
else{_b_.getattr(res, "__setitem__")(key,value)}
Sep 5, 2014
517
}catch(err){
518
if($B.is_exc(err,[_b_.StopIteration])){
519
return res
520
}
521
throw err
522
}
523
}
524
}
525
$DictDict.fromkeys.$type = 'classmethod'
Sep 5, 2014
526
Nov 21, 2015
527
$DictDict.get = function(){
528
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
529
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
531
try{return $DictDict.__getitem__($.self, $.key)}
532
catch(err){
533
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
534
else{throw err}
535
}
536
}
537
538
var $dict_itemsDict = $B.$iterator_class('dict_items')
539
540
$DictDict.items = function(self){
541
if (arguments.length > 1) {
542
var _len=arguments.length - 1
543
var _msg="items() takes no arguments ("+_len+" given)"
544
throw _b_.TypeError(_msg)
545
}
546
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
547
}
548
Nov 21, 2015
549
var $dict_keysDict = $B.$iterator_class('dict_keys')
550
551
$DictDict.keys = function(self){
552
if (arguments.length > 1) {
553
var _len=arguments.length - 1
554
var _msg="keys() takes no arguments ("+_len+" given)"
555
throw _b_.TypeError(_msg)
556
}
557
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
558
}
559
560
$DictDict.pop = function(){
561
562
var $ = $B.args('pop', 3, {self:null, key: null, _default:null},
563
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
564
self=$.self, key=$.key, _default=$._default
565
Sep 5, 2014
566
try{
567
var res = $DictDict.__getitem__(self,key)
568
$DictDict.__delitem__(self,key)
569
return res
570
}catch(err){
571
if(err.__name__==='KeyError'){
572
if(_default!==undefined) return _default
573
throw err
574
}
575
throw err
576
}
577
}
578
579
$DictDict.popitem = function(self){
580
try{
581
var itm = new $item_iterator(self).next()
582
$DictDict.__delitem__(self,itm[0])
583
return _b_.tuple(itm)
584
}catch(err) {
585
if (err.__name__ == "StopIteration") {
586
throw KeyError("'popitem(): dictionary is empty'")
587
}
588
}
Sep 5, 2014
589
}
590
Nov 21, 2015
591
$DictDict.setdefault = function(){
592
593
var $ = $B.args('setdefault', 3, {self:null, key: null, _default:null},
594
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
Nov 21, 2015
595
self=$.self, key=$.key, _default=$._default
596
Sep 5, 2014
597
try{return $DictDict.__getitem__(self,key)}
598
catch(err){
599
if(_default===undefined) _default=$N
Sep 5, 2014
600
$DictDict.__setitem__(self,key,_default)
601
return _default
602
}
603
}
604
605
$DictDict.update = function(self){
Nov 21, 2015
606
607
var $ = $B.args('update',1,{'self':null},['self'],arguments,{},'args','kw'),
608
self=$.self, args=$.args, kw=$.kw
609
610
if(args.length>0) {
611
var o=args[0]
612
if (isinstance(o,dict)){
613
$copy_dict(self, o)
614
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
615
var _keys=_b_.list(getattr(o, 'keys')())
616
var si=$DictDict.__setitem__
617
var i=_keys.length
618
while(i--) {
619
//for (var i=0; i < _keys.length; i++) {
620
var _value = getattr(o, '__getitem__')(_keys[i])
621
si(self, _keys[i], _value)
Sep 5, 2014
624
}
Sep 5, 2014
627
}
628
Nov 21, 2015
629
var $dict_valuesDict = $B.$iterator_class('dict_values')
630
631
$DictDict.values = function(self){
632
if (arguments.length > 1) {
633
var _len=arguments.length - 1
634
var _msg="values() takes no arguments ("+_len+" given)"
635
throw _b_.TypeError(_msg)
636
}
637
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
638
}
639
640
function dict(args, second){
642
var res = {__class__:$DictDict,
643
$numeric_dict : {},
644
$object_dict : {},
645
$string_dict : {},
646
$str_hash: {},
647
length: 0
648
}
650
if(args===undefined){return res}
652
if(second===undefined){
653
if(Array.isArray(args)){
654
// Form "dict([[key1, value1], [key2,value2], ...])"
655
var i = -1, stop = args.length-1
656
var si = $DictDict.__setitem__
657
while(i++<stop){
658
var item=args[i]
659
switch(typeof item[0]) {
660
case 'string':
661
res.$string_dict[item[0]]=item[1]
662
res.$str_hash[str_hash(item[0])]=item[0]
663
break;
664
case 'number':
665
res.$numeric_dict[item[0]]=item[1]
666
break
667
default:
668
si(res, item[0], item[1])
669
break
670
}
671
}
672
return res
673
}else if(args.$nat=='kw'){
674
// Form dict(k1=v1, k2=v2...)
675
var kw = args['kw']
676
for(var attr in kw){
677
switch(typeof attr) {
678
case 'string':
679
res.$string_dict[attr]=kw[attr]
680
res.$str_hash[str_hash(attr)]=attr
681
break;
682
case 'number':
683
res.$numeric_dict[attr]=kw[attr]
684
break
685
default:
686
si(res, attr, kw[attr])
687
break
688
}
Sep 5, 2014
694
// apply __init__ with arguments of dict()
695
var _args = [res], pos=1
696
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
697
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
698
return res
699
}
Sep 5, 2014
701
dict.__class__ = $B.$factory
702
dict.$dict = $DictDict
703
$DictDict.$factory = dict
704
$DictDict.__new__ = $B.$__new__(dict)
705
706
_b_.dict = dict
708
$B.set_func_names($DictDict)
709
710
// following are used for faster access elsewhere
711
$B.$dict_iterator = function(d) { return new $item_generator(d) }
712
$B.$dict_length = $DictDict.__len__
713
$B.$dict_getitem = $DictDict.__getitem__
714
$B.$dict_get = $DictDict.get
715
$B.$dict_set = $DictDict.__setitem__
716
$B.$dict_contains = $DictDict.__contains__
717
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
718
$B.$copy_dict = $copy_dict // copy from right to left
719
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
720
722
// Class for attribute __dict__ of classes
723
var mappingproxyDict = {
724
__class__ : $B.$type,
725
__name__ : "mappingproxy"
726
}
727
mappingproxyDict.__mro__ = [_b_.object.$dict]
728
729
mappingproxyDict.__setitem__ = function(){
730
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
731
}
732
734
function mappingproxy(obj){
735
var res = obj_dict(obj)
736
res.__class__ = mappingproxyDict
737
return res
738
}
739
mappingproxy.__class__ = $B.$factory
740
mappingproxy.$dict = mappingproxyDict
741
mappingproxyDict.$factory = mappingproxy
742
$B.mappingproxy = mappingproxy
743
744
$B.obj_dict = function(obj){
745
var klass = $B.get_class(obj)
746
if(klass !==undefined && klass.$native){
747
throw _b_.AttributeError(klass.__name__+
748
" has no attribute '__dict__'")}
749
var res = dict()
750
res.$jsobj = obj
751
res.$to_dict = (function(x){
752
return function(){
753
var d = dict()
754
for(var attr in x){
755
if(attr.charAt(0)!='$' && attr!=='__class__'){
756
d.$string_dict[attr] = x[attr]
757
d.length++
758
}
759
}
760
return d
761
}
762
})(obj)
763
return res
764
}
765
Sep 5, 2014
766
})(__BRYTHON__)