Skip to content
Permalink
Newer
Older
100644 764 lines (648 sloc) 21.2 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 $B.rich_comp("__eq__", toSet(items), other)
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.rich_comp("__eq__", item, self.$str_hash[_key])){return true}
155
if (self.$numeric_dict[_key]!==undefined &&
156
$B.rich_comp("__eq__", item, _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
168
return $B.rich_comp("__eq__", item, self.$object_dict[_key][0])
169
}
170
return false
Sep 5, 2014
171
}
172
Nov 21, 2015
173
$DictDict.__delitem__ = function(){
174
175
var $ = $B.args('__eq__', 2, {self:null, arg:null},
176
['self', 'arg'], arguments, {}, null, null),
177
self=$.self, arg=$.arg
178
179
if(self.$jsobj){
180
if(self.$jsobj[arg]===undefined){throw KeyError(arg)}
181
delete self.$jsobj[arg]
184
switch(typeof arg) {
185
case 'string':
186
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
187
delete self.$string_dict[arg]
188
delete self.$str_hash[str_hash(arg)]
190
case 'number':
191
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
192
delete self.$numeric_dict[arg]
195
// go with defaults
197
var _key=hash(arg)
199
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
200
delete self.$object_dict[_key]
202
203
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
205
}
206
Nov 21, 2015
207
$DictDict.__eq__ = function(){
208
var $ = $B.args('__eq__', 2, {self:null, other:null},
209
['self', 'other'], arguments, {}, null, null),
210
self=$.self, other=$.other
211
212
if(!isinstance(other,dict)) return false
213
214
if(self.$jsobj){self=self.$to_dict()}
215
if(other.$jsobj){other=other.$to_dict()}
216
217
if ($DictDict.__len__(self) != $DictDict.__len__(other)){return false}
Nov 21, 2015
219
if((self.$numeric_dict.length!=other.$numeric_dict.length) ||
220
(self.$string_dict.length!=other.$string_dict.length) ||
221
(self.$object_dict.length!=other.$object_dict.length)){
222
return false
Nov 21, 2015
224
for(var k in self.$numeric_dict){
225
if(!$B.rich_comp("__eq__", other.$numeric_dict[k], self.$numeric_dict[k])){
Nov 21, 2015
226
return false
227
}
228
}
229
for(var k in self.$string_dict){
230
if(!$B.rich_comp("__eq__", other.$string_dict[k], self.$string_dict[k])){
Nov 21, 2015
231
return false
232
}
233
}
234
for(var k in self.$object_dict){
235
if(!$B.rich_comp("__eq__", other.$object_dict[k][1], self.$object_dict[k][1])){
Nov 21, 2015
236
return false
237
}
238
}
Nov 21, 2015
241
Sep 5, 2014
242
}
243
Nov 21, 2015
244
$DictDict.__getitem__ = function(){
245
var $ = $B.args('__getitem__', 2, {self:null, arg:null},
246
['self', 'arg'], arguments, {}, null, null),
247
self=$.self, arg=$.arg
248
249
if(self.$jsobj){
250
if(self.$jsobj[arg]===undefined || self.$jsobj[arg]===null){return $N}
251
return self.$jsobj[arg]
252
}
253
254
255
switch(typeof arg) {
256
case 'string':
257
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
258
break
259
case 'number':
260
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
263
// since the key is more complex use 'default' method of getting item
264
265
var _key = _b_.hash(arg),
266
_eq = function(other){return $B.rich_comp('__eq__', arg, other)}
268
var sk = self.$str_hash[_key]
269
if (sk!==undefined && _eq(sk)){
270
return self.$string_dict[sk]
271
}
272
if (self.$numeric_dict[_key]!==undefined && _eq(_key)){
273
return self.$numeric_dict[_key]
275
276
var obj_ref = self.$object_dict[_key]
277
if(obj_ref!==undefined){
278
// An object with the same hash is already stored
279
// Lookup should fail if equality raises an exception
280
_eq(self.$object_dict[_key][0])
Nov 21, 2015
281
return self.$object_dict[_key][1]
283
if(self.__class__!==$DictDict){
284
try{
285
var missing_method = getattr(self.__class__.$factory, '__missing__')
286
return missing_method(self, arg)
287
}catch(err){}
288
}
Sep 5, 2014
289
throw KeyError(_b_.str(arg))
290
}
291
292
$DictDict.__hash__ = None
Sep 5, 2014
293
294
$DictDict.__init__ = function(self){
295
var args = [], pos=0
296
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
298
switch(args.length) {
299
case 0:
300
return
301
case 1:
Sep 5, 2014
302
var obj = args[0]
303
if(Array.isArray(obj)){
304
var i = obj.length
305
var si = $DictDict.__setitem__
306
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
308
}else if(obj.$nat===undefined && isinstance(obj,dict)){
Sep 5, 2014
311
}
Sep 5, 2014
313
if(obj.__class__===$B.JSObject.$dict){
314
// convert a JSObject into a Python dictionary
316
// Attribute $jsobj is used to update the original JS object
317
// when the dictionary is modified
Sep 5, 2014
320
}
323
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
324
var args = $ns['args']
325
var kw = $ns['kw']
Sep 5, 2014
328
if(isinstance(args[0],dict)){
Sep 5, 2014
331
}
Sep 5, 2014
333
// format dict([(k1,v1),(k2,v2)...])
335
if(Array.isArray(args[0])){
336
var src = args[0]
338
var si=$DictDict.__setitem__
339
while(i-->0) si(self, src[i-1][0], src[i-1][1])
341
var iterable = $B.$iter(args[0]),
342
ce = $B.current_exception
343
while(1){
344
try{
345
var elt = next(iterable)
346
var key = getattr(elt,'__getitem__')(0)
347
var value = getattr(elt,'__getitem__')(1)
348
$DictDict.__setitem__(self, key, value)
349
}catch(err){
350
if(err.__name__==='StopIteration'){
351
$B.current_exception = ce
352
break
353
}
Sep 5, 2014
356
}
357
}
359
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
361
}
362
363
var $dict_iterator = $B.$iterator_class('dict iterator')
364
$DictDict.__iter__ = function(self) {
365
return $DictDict.keys(self)
Sep 5, 2014
366
}
367
368
$DictDict.__len__ = function(self) {
369
var _count=0
371
if(self.$jsobj){
372
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
373
return _count
374
}
376
for (var k in self.$numeric_dict) _count++
377
for (var k in self.$string_dict) _count++
378
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
380
return _count
Sep 5, 2014
382
383
$DictDict.__mro__ = [$ObjectDict]
Sep 5, 2014
384
385
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
386
387
$DictDict.__next__ = function(self){
389
self.$iter = new $item_generator(self)
390
}
391
try {
392
return self.$iter.next()
393
} catch (err) {
394
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
395
}
396
}
397
398
$DictDict.__repr__ = function(self){
399
if(self===undefined) return "<class 'dict'>"
400
if(self.$jsobj){ // wrapper around Javascript object
401
return $DictDict.__repr__(self.$to_dict())
403
var res=[],
404
pos=0,
405
items = new $item_generator(self).as_list()
406
for (var i=0; i < items.length; i++) {
407
var itm = items[i]
408
if(itm[1]===self){res[pos++]=repr(itm[0])+': {...}'}
409
else{res[pos++]=repr(itm[0])+': '+repr(itm[1])}
Sep 5, 2014
410
}
411
return '{'+ res.join(', ') +'}'
Sep 5, 2014
412
}
413
414
$DictDict.__setitem__ = function(self,key,value){
Nov 21, 2015
416
var $ = $B.args('__setitem__', 3, {self:null, key:null, value:null},
417
['self', 'key', 'value'], arguments, {}, null, null),
418
self=$.self, key=$.key, value=$.value
419
420
if(self.$jsobj){
421
if (value === $N) self.$jsobj[key] = undefined;
422
else self.$jsobj[key]=value;
423
return
424
}
426
switch(typeof key) {
427
case 'string':
428
self.$string_dict[key]=value
429
self.$str_hash[str_hash(key)]=key
431
case 'number':
432
self.$numeric_dict[key]=value
436
// if we got here the key is more complex, use default method
438
var _key=hash(key)
439
var _eq=function(other){return $B.rich_comp("__eq__", key, other)};
441
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
442
self.$numeric_dict[_key] = value
444
}
445
var sk = self.$str_hash[_key]
446
if(sk!==undefined && _eq(sk)){
447
self.$string_dict[sk] = value
449
}
450
451
var obj_ref = self.$object_dict[_key]
452
if(obj_ref!==undefined){
453
// An object with the same hash is already stored
454
// Lookup should fail if equality raises an exception
455
_eq(self.$object_dict[_key][0])
456
}
457
self.$object_dict[_key] = [key, value]
Sep 5, 2014
459
}
460
461
$DictDict.__str__ = $DictDict.__repr__
462
463
// add "reflected" methods
464
$B.make_rmethods($DictDict)
465
466
$DictDict.clear = function(){
Sep 5, 2014
467
// Remove all items from the dictionary.
468
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
469
self = $.self
471
self.$numeric_dict={}
472
self.$string_dict={}
473
self.$str_hash={}
474
self.$object_dict={}
476
if(self.$jsobj){
477
for(var attr in self.$jsobj){
478
if(attr.charAt(0) !== '$' && attr !== "__class__"){
479
delete self.$jsobj[attr]
480
}
481
}
482
}
Sep 5, 2014
484
}
485
486
$DictDict.copy = function(self){
487
// Return a shallow copy of the dictionary
488
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
489
self = $.self,
490
res = _b_.dict()
Sep 5, 2014
492
return res
493
}
494
Nov 21, 2015
495
$DictDict.fromkeys = function(){
496
497
var $ = $B.args('fromkeys', 3, {cls:null, keys:null, value:null},
498
['cls', 'keys', 'value'], arguments, {value:_b_.None}, null, null),
Nov 21, 2015
499
keys=$.keys, value=$.value
Sep 5, 2014
501
// class method
502
var klass = $.cls,
503
res = klass(),
504
keys_iter = $B.$iter(keys),
505
ce = $B.current_exception
Sep 5, 2014
507
while(1){
508
try{
509
var key = _b_.next(keys_iter)
510
if(klass===dict){$DictDict.__setitem__(res, key, value)}
511
else{_b_.getattr(res, "__setitem__")(key,value)}
Sep 5, 2014
512
}catch(err){
513
if($B.is_exc(err,[_b_.StopIteration])){
Sep 5, 2014
515
return res
516
}
517
throw err
518
}
519
}
520
}
521
$DictDict.fromkeys.$type = 'classmethod'
Sep 5, 2014
522
Nov 21, 2015
523
$DictDict.get = function(){
524
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
525
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
527
try{return $DictDict.__getitem__($.self, $.key)}
528
catch(err){
529
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
530
else{throw err}
531
}
532
}
533
534
var $dict_itemsDict = $B.$iterator_class('dict_items')
535
536
$DictDict.items = function(self){
537
if (arguments.length > 1) {
538
var _len=arguments.length - 1
539
var _msg="items() takes no arguments ("+_len+" given)"
540
throw _b_.TypeError(_msg)
541
}
542
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
543
}
544
Nov 21, 2015
545
var $dict_keysDict = $B.$iterator_class('dict_keys')
546
547
$DictDict.keys = function(self){
548
if (arguments.length > 1) {
549
var _len=arguments.length - 1
550
var _msg="keys() takes no arguments ("+_len+" given)"
551
throw _b_.TypeError(_msg)
552
}
553
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
554
}
555
556
$DictDict.pop = function(){
557
558
var $ = $B.args('pop', 3, {self:null, key: null, _default:null},
559
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
560
self=$.self, key=$.key, _default=$._default
561
Sep 5, 2014
562
try{
563
var res = $DictDict.__getitem__(self,key)
564
$DictDict.__delitem__(self,key)
565
return res
566
}catch(err){
567
if(err.__name__==='KeyError'){
568
if(_default!==undefined) return _default
569
throw err
570
}
571
throw err
572
}
573
}
574
575
$DictDict.popitem = function(self){
577
try{
578
var itm = new $item_iterator(self).next()
579
$DictDict.__delitem__(self,itm[0])
580
return _b_.tuple(itm)
581
}catch(err) {
582
if (err.__name__ == "StopIteration") {
584
throw KeyError("'popitem(): dictionary is empty'")
585
}
586
}
Sep 5, 2014
587
}
588
Nov 21, 2015
589
$DictDict.setdefault = function(){
590
591
var $ = $B.args('setdefault', 3, {self:null, key: null, _default:null},
592
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
Nov 21, 2015
593
self=$.self, key=$.key, _default=$._default
594
Sep 5, 2014
595
try{return $DictDict.__getitem__(self,key)}
596
catch(err){
597
if(_default===undefined) _default=$N
Sep 5, 2014
598
$DictDict.__setitem__(self,key,_default)
599
return _default
600
}
601
}
602
603
$DictDict.update = function(self){
Nov 21, 2015
604
605
var $ = $B.args('update',1,{'self':null},['self'],arguments,{},'args','kw'),
606
self=$.self, args=$.args, kw=$.kw
607
608
if(args.length>0) {
609
var o=args[0]
610
if (isinstance(o,dict)){
611
$copy_dict(self, o)
612
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
613
var _keys=_b_.list(getattr(o, 'keys')())
614
var si=$DictDict.__setitem__
615
var i=_keys.length
616
while(i--) {
617
//for (var i=0; i < _keys.length; i++) {
618
var _value = getattr(o, '__getitem__')(_keys[i])
619
si(self, _keys[i], _value)
Sep 5, 2014
622
}
Sep 5, 2014
625
}
626
Nov 21, 2015
627
var $dict_valuesDict = $B.$iterator_class('dict_values')
628
629
$DictDict.values = function(self){
630
if (arguments.length > 1) {
631
var _len=arguments.length - 1
632
var _msg="values() takes no arguments ("+_len+" given)"
633
throw _b_.TypeError(_msg)
634
}
635
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
636
}
637
638
function dict(args, second){
640
var res = {__class__:$DictDict,
641
$numeric_dict : {},
642
$object_dict : {},
643
$string_dict : {},
644
$str_hash: {},
645
length: 0
646
}
648
if(args===undefined){return res}
650
if(second===undefined){
651
if(Array.isArray(args)){
652
// Form "dict([[key1, value1], [key2,value2], ...])"
653
var i = -1, stop = args.length-1
654
var si = $DictDict.__setitem__
655
while(i++<stop){
656
var item=args[i]
657
switch(typeof item[0]) {
658
case 'string':
659
res.$string_dict[item[0]]=item[1]
660
res.$str_hash[str_hash(item[0])]=item[0]
661
break;
662
case 'number':
663
res.$numeric_dict[item[0]]=item[1]
664
break
665
default:
666
si(res, item[0], item[1])
667
break
668
}
669
}
670
return res
671
}else if(args.$nat=='kw'){
672
// Form dict(k1=v1, k2=v2...)
673
var kw = args['kw']
674
for(var attr in kw){
675
switch(typeof attr) {
676
case 'string':
677
res.$string_dict[attr]=kw[attr]
678
res.$str_hash[str_hash(attr)]=attr
679
break;
680
case 'number':
681
res.$numeric_dict[attr]=kw[attr]
682
break
683
default:
684
si(res, attr, kw[attr])
685
break
686
}
Sep 5, 2014
692
// apply __init__ with arguments of dict()
693
var _args = [res], pos=1
694
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
695
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
696
return res
697
}
Sep 5, 2014
699
dict.__class__ = $B.$factory
700
dict.$dict = $DictDict
701
$DictDict.$factory = dict
702
$DictDict.__new__ = $B.$__new__(dict)
703
704
_b_.dict = dict
706
$B.set_func_names($DictDict)
707
708
// following are used for faster access elsewhere
709
$B.$dict_iterator = function(d) { return new $item_generator(d) }
710
$B.$dict_length = $DictDict.__len__
711
$B.$dict_getitem = $DictDict.__getitem__
712
$B.$dict_get = $DictDict.get
713
$B.$dict_set = $DictDict.__setitem__
714
$B.$dict_contains = $DictDict.__contains__
715
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
716
$B.$copy_dict = $copy_dict // copy from right to left
717
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
718
720
// Class for attribute __dict__ of classes
721
var mappingproxyDict = {
722
__class__ : $B.$type,
723
__name__ : "mappingproxy"
724
}
725
mappingproxyDict.__mro__ = [_b_.object.$dict]
726
727
mappingproxyDict.__setitem__ = function(){
728
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
729
}
730
732
function mappingproxy(obj){
733
var res = obj_dict(obj)
734
res.__class__ = mappingproxyDict
735
return res
736
}
737
mappingproxy.__class__ = $B.$factory
738
mappingproxy.$dict = mappingproxyDict
739
mappingproxyDict.$factory = mappingproxy
740
$B.mappingproxy = mappingproxy
741
742
$B.obj_dict = function(obj){
743
var klass = $B.get_class(obj)
744
if(klass !==undefined && klass.$native){
745
throw _b_.AttributeError(klass.__name__+
746
" has no attribute '__dict__'")}
747
var res = dict()
748
res.$jsobj = obj
749
res.$to_dict = (function(x){
750
return function(){
751
var d = dict()
752
for(var attr in x){
753
if(attr.charAt(0)!='$' && attr!=='__class__'){
754
d.$string_dict[attr] = x[attr]
755
d.length++
756
}
757
}
758
return d
759
}
760
})(obj)
761
return res
762
}
763
Sep 5, 2014
764
})(__BRYTHON__)