Skip to content
Permalink
Newer
Older
100644 739 lines (623 sloc) 20.4 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 = []
48
for(var attr in d.$jsobj){
49
if(attr.charAt(0)!='$'){this.items.push([attr,d.$jsobj[attr]])}
50
}
51
this.length=this.items.length;
52
return
53
}
54
55
var items=[]
58
items[pos++]=[parseFloat(k), d.$numeric_dict[k]]
61
for (var k in d.$string_dict) {items[pos++]=[k, d.$string_dict[k]]}
63
for (var k in d.$object_dict) {items[pos++] = d.$object_dict[k]}
64
65
this.items=items
66
this.length=items.length
Feb 9, 2015
68
69
$item_generator.prototype.next = function() {
70
if (this.i < this.items.length) {
71
return this.items[this.i++]
72
}
73
throw _b_.StopIteration("StopIteration")
74
}
75
$item_generator.prototype.as_list = function() {
76
return this.items
77
}
78
79
var $item_iterator = function(d) {
80
this.d = d
81
this.current = 0
82
this.iter = new $item_generator(d)
83
}
84
$item_iterator.prototype.length = function() {return this.iter.items.length }
85
$item_iterator.prototype.next = function() { return _b_.tuple(this.iter.next()) }
86
87
var $copy_dict = function(left, right) {
88
var _l=new $item_generator(right).as_list()
89
var si=$DictDict.__setitem__
90
var i=_l.length
91
while(i--) si(left, _l[i][0], _l[i][1])
94
function toSet(items){
95
// Build a set from the iteration on items
96
var res = []
97
while(true){
98
try{res.push(items.next())}
99
catch(err){break}
100
}
101
return _b_.set(res)
102
}
103
104
var $iterator_wrapper = function(items,klass){
105
var res = {
106
__class__:klass,
107
__eq__:function(other){
108
// compare set of items to other
109
return getattr(toSet(items), "__eq__")(other)
110
},
111
__iter__:function(){items.iter.i=0; return res},
112
__len__:function(){return items.length()},
113
__next__:function(){
114
return items.next()
115
},
116
__repr__:function(){
117
var s = []
118
for(var i=0, len=items.length(); i<len; i++){
119
s.push(_b_.repr(items.next()))
120
}
121
return klass.__name__+'(['+ s.join(',') + '])'
122
},
123
}
124
res.__str__ = res.toString = res.__repr__
125
return res
126
}
127
128
$DictDict.__bool__ = function () {
Nov 21, 2015
129
var $=$B.args('__bool__',1,{self:null},['self'],arguments,{},null,null)
130
return $DictDict.__len__($.self) > 0
133
$DictDict.__contains__ = function(){
Nov 21, 2015
134
135
var $ = $B.args('__contains__', 2, {self:null, item:null},
136
['self', 'item'], arguments, {}, null, null),
137
self=$.self, item=$.item
Nov 21, 2015
138
Sep 5, 2014
139
if(self.$jsobj) return self.$jsobj[item]!==undefined
Nov 21, 2015
140
141
switch(typeof item) {
142
case 'string':
143
return self.$string_dict[item] !==undefined
144
case 'number':
145
return self.$numeric_dict[item] !==undefined
147
148
var _key=hash(item)
149
if (self.$str_hash[_key]!==undefined &&
150
_b_.getattr(item,'__eq__')(self.$str_hash[_key])){return true}
151
if (self.$numeric_dict[_key]!==undefined &&
152
_b_.getattr(item,'__eq__')(_key)){return true}
153
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
154
// If the key is an object, its hash must be in the dict keys but the
155
// key itself must compare equal to the key associated with the hash
156
// For instance :
157
//
158
// class X:
159
// def __hash__(self): return hash('u')
160
//
161
// a = {'u': 'a', X(): 'b'}
162
// assert set(a.values())=={'a', 'b'}
163
// assert not X() in a
164
165
var _eq = getattr(item, '__eq__')
Nov 21, 2015
166
if(_eq(self.$object_dict[_key][0])){return true}
167
}
168
return false
Sep 5, 2014
169
}
170
Nov 21, 2015
171
$DictDict.__delitem__ = function(){
172
173
var $ = $B.args('__eq__', 2, {self:null, arg:null},
174
['self', 'arg'], arguments, {}, null, null),
175
self=$.self, arg=$.arg
176
177
if(self.$jsobj){
178
if(self.$jsobj[arg]===undefined){throw KeyError(arg)}
179
delete self.$jsobj[arg]
182
switch(typeof arg) {
183
case 'string':
184
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
185
delete self.$string_dict[arg]
186
delete self.$str_hash[str_hash(arg)]
188
case 'number':
189
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
190
delete self.$numeric_dict[arg]
193
// go with defaults
195
var _key=hash(arg)
Nov 21, 2015
196
197
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
198
delete self.$object_dict[_key]
200
201
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
203
}
204
Nov 21, 2015
205
$DictDict.__eq__ = function(){
206
var $ = $B.args('__eq__', 2, {self:null, other:null},
207
['self', 'other'], arguments, {}, null, null),
208
self=$.self, other=$.other
209
210
if(!isinstance(other,dict)) return false
212
if ($DictDict.__len__(self) != $DictDict.__len__(other)){return false}
Nov 21, 2015
214
if((self.$numeric_dict.length!=other.$numeric_dict.length) ||
215
(self.$string_dict.length!=other.$string_dict.length) ||
216
(self.$object_dict.length!=other.$object_dict.length)){
217
return false
Nov 21, 2015
219
for(var k in self.$numeric_dict){
220
if(!_b_.getattr(other.$numeric_dict[k],'__eq__')(self.$numeric_dict[k])){
221
return false
222
}
223
}
224
for(var k in self.$string_dict){
225
if(!_b_.getattr(other.$string_dict[k],'__eq__')(self.$string_dict[k])){
226
return false
227
}
228
}
229
for(var k in self.$object_dict){
230
console.log('key in object dict', k)
Nov 21, 2015
231
if(!_b_.getattr(other.$object_dict[k][1],'__eq__')(self.$object_dict[k][1])){
232
return false
233
}
234
}
235
Nov 21, 2015
237
Sep 5, 2014
238
}
239
Nov 21, 2015
240
$DictDict.__getitem__ = function(){
241
var $ = $B.args('__getitem__', 2, {self:null, arg:null},
242
['self', 'arg'], arguments, {}, null, null),
243
self=$.self, arg=$.arg
244
245
if(self.$jsobj){
246
if(self.$jsobj[arg]===undefined){return None}
247
return self.$jsobj[arg]
248
}
251
switch(typeof arg) {
252
case 'string':
253
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
254
break
255
case 'number':
256
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
259
// since the key is more complex use 'default' method of getting item
260
261
var _key = _b_.hash(arg),
262
_eq = _b_.getattr(arg, '__eq__')
263
264
var sk = self.$str_hash[_key]
265
if (sk!==undefined && _eq(sk)){
266
return self.$string_dict[sk]
267
}
268
if (self.$numeric_dict[_key]!==undefined && _eq(_key)){
269
return self.$numeric_dict[_key]
271
272
var obj_ref = self.$object_dict[_key]
273
if(obj_ref!==undefined){
274
// An object with the same hash is already stored
275
// Lookup should fail if equality raises an exception
276
_eq(self.$object_dict[_key][0])
Nov 21, 2015
277
return self.$object_dict[_key][1]
279
if(self.__class__!==$DictDict){
280
try{
281
var missing_method = getattr(self.__class__.$factory, '__missing__')
282
return missing_method(self, arg)
283
}catch(err){}
284
}
Sep 5, 2014
285
throw KeyError(_b_.str(arg))
286
}
287
288
$DictDict.__hash__ = None
Sep 5, 2014
289
290
$DictDict.__init__ = function(self){
291
var args = [], pos=0
292
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
294
switch(args.length) {
295
case 0:
296
return
297
case 1:
Sep 5, 2014
298
var obj = args[0]
299
if(Array.isArray(obj)){
300
var i = obj.length
301
var si = $DictDict.__setitem__
302
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
304
}else if(obj.$nat===undefined && isinstance(obj,dict)){
Sep 5, 2014
307
}
Sep 5, 2014
309
if(obj.__class__===$B.JSObject.$dict){
310
// convert a JSObject into a Python dictionary
311
var si = $DictDict.__setitem__
312
for(var attr in obj.js) si(self,attr,obj.js[attr])
313
314
// Attribute $jsobj is used to update the original JS object
315
// when the dictionary is modified
Sep 5, 2014
318
}
321
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
322
var args = $ns['args']
323
var kw = $ns['kw']
Sep 5, 2014
326
if(isinstance(args[0],dict)){
Sep 5, 2014
329
}
Sep 5, 2014
331
// format dict([(k1,v1),(k2,v2)...])
332
333
if(Array.isArray(args[0])){
334
var src = args[0]
336
var si=$DictDict.__setitem__
337
while(i-->0) si(self, src[i-1][0], src[i-1][1])
339
var iterable = $B.$iter(args[0])
340
while(1){
341
try{
342
var elt = next(iterable)
343
var key = getattr(elt,'__getitem__')(0)
344
var value = getattr(elt,'__getitem__')(1)
345
$DictDict.__setitem__(self, key, value)
346
}catch(err){
347
if(err.__name__==='StopIteration'){break}
Sep 5, 2014
350
}
351
}
353
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
355
}
356
357
var $dict_iterator = $B.$iterator_class('dict iterator')
358
$DictDict.__iter__ = function(self) {
359
return $DictDict.keys(self)
Sep 5, 2014
360
}
361
362
$DictDict.__len__ = function(self) {
363
var _count=0
364
365
if(self.$jsobj){
366
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
367
return _count
368
}
370
for (var k in self.$numeric_dict) _count++
371
for (var k in self.$string_dict) _count++
372
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
374
return _count
Sep 5, 2014
376
377
$DictDict.__mro__ = [$ObjectDict]
Sep 5, 2014
378
379
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
380
381
$DictDict.__next__ = function(self){
383
self.$iter = new $item_generator(self)
384
}
385
try {
386
return self.$iter.next()
387
} catch (err) {
388
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
389
}
390
}
391
392
$DictDict.__repr__ = function(self){
393
if(self===undefined) return "<class 'dict'>"
394
if(self.$jsobj){ // wrapper around Javascript object
395
var res = []
396
for(var attr in self.$jsobj){
397
if(attr.charAt(0)=='$' || attr=='__class__'){continue}
Nov 4, 2015
398
else{
399
try{
400
res.push("'"+attr+"': "+_b_.repr(self.$jsobj[attr]))
401
}catch(err){
402
// FIX ME
403
}
404
}
405
}
406
return '{'+res.join(', ')+'}'
407
}
408
var res=[],
409
pos=0,
410
items = new $item_generator(self).as_list()
411
for (var i=0; i < items.length; i++) {
412
var itm = items[i]
413
if(itm[1]===self){res[pos++]=repr(itm[0])+': {...}'}
414
else{res[pos++]=repr(itm[0])+': '+repr(itm[1])}
Sep 5, 2014
415
}
416
return '{'+ res.join(', ') +'}'
Sep 5, 2014
417
}
418
419
$DictDict.__setitem__ = function(self,key,value){
Nov 21, 2015
421
var $ = $B.args('__setitem__', 3, {self:null, key:null, value:null},
422
['self', 'key', 'value'], arguments, {}, null, null),
423
self=$.self, key=$.key, value=$.value
424
425
if(self.$jsobj){self.$jsobj[key]=value;return}
426
427
switch(typeof key) {
428
case 'string':
429
self.$string_dict[key]=value
430
self.$str_hash[str_hash(key)]=key
432
case 'number':
433
self.$numeric_dict[key]=value
437
// if we got here the key is more complex, use default method
439
var _key=hash(key)
440
var _eq=getattr(key, '__eq__')
442
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
443
self.$numeric_dict[_key] = value
445
}
446
var sk = self.$str_hash[_key]
447
if(sk!==undefined && _eq(sk)){
448
self.$string_dict[sk] = value
450
}
451
452
var obj_ref = self.$object_dict[_key]
453
if(obj_ref!==undefined){
454
// An object with the same hash is already stored
455
// Lookup should fail if equality raises an exception
456
_eq(self.$object_dict[_key][0])
457
}
458
self.$object_dict[_key] = [key, value]
Sep 5, 2014
460
}
461
462
$DictDict.__str__ = $DictDict.__repr__
463
464
// add "reflected" methods
465
$B.make_rmethods($DictDict)
466
467
$DictDict.clear = function(){
Sep 5, 2014
468
// Remove all items from the dictionary.
469
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
470
self = $.self
472
self.$numeric_dict={}
473
self.$string_dict={}
474
self.$str_hash={}
475
self.$object_dict={}
Sep 5, 2014
477
if(self.$jsobj) self.$jsobj={}
Sep 5, 2014
479
}
480
481
$DictDict.copy = function(self){
482
// Return a shallow copy of the dictionary
483
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
484
self = $.self,
485
res = _b_.dict()
Sep 5, 2014
487
return res
488
}
489
Nov 21, 2015
490
$DictDict.fromkeys = function(){
491
492
var $ = $B.args('fromkeys', 3, {cls:null, keys:null, value:null},
493
['cls', 'keys', 'value'], arguments, {value:_b_.None}, null, null),
Nov 21, 2015
494
keys=$.keys, value=$.value
Sep 5, 2014
496
// class method
497
var klass = $.cls,
498
res = klass(),
Sep 5, 2014
501
while(1){
502
try{
503
var key = _b_.next(keys_iter)
504
if(klass===dict){$DictDict.__setitem__(res, key, value)}
505
else{_b_.getattr(res, "__setitem__")(key,value)}
Sep 5, 2014
506
}catch(err){
507
if($B.is_exc(err,[_b_.StopIteration])){
508
return res
509
}
510
throw err
511
}
512
}
513
}
514
$DictDict.fromkeys.$type = 'classmethod'
Sep 5, 2014
515
Nov 21, 2015
516
$DictDict.get = function(){
517
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
518
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
520
try{return $DictDict.__getitem__($.self, $.key)}
521
catch(err){
522
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
523
else{throw err}
524
}
525
}
526
527
var $dict_itemsDict = $B.$iterator_class('dict_items')
528
529
$DictDict.items = function(self){
530
if (arguments.length > 1) {
531
var _len=arguments.length - 1
532
var _msg="items() takes no arguments ("+_len+" given)"
533
throw _b_.TypeError(_msg)
534
}
535
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
536
}
537
Nov 21, 2015
538
var $dict_keysDict = $B.$iterator_class('dict_keys')
539
540
$DictDict.keys = function(self){
541
if (arguments.length > 1) {
542
var _len=arguments.length - 1
543
var _msg="keys() takes no arguments ("+_len+" given)"
544
throw _b_.TypeError(_msg)
545
}
546
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
547
}
548
549
$DictDict.pop = function(){
550
551
var $ = $B.args('pop', 3, {self:null, key: null, _default:null},
552
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
553
self=$.self, key=$.key, _default=$._default
554
Sep 5, 2014
555
try{
556
var res = $DictDict.__getitem__(self,key)
557
$DictDict.__delitem__(self,key)
558
return res
559
}catch(err){
560
if(err.__name__==='KeyError'){
561
if(_default!==undefined) return _default
562
throw err
563
}
564
throw err
565
}
566
}
567
568
$DictDict.popitem = function(self){
569
try{
570
var itm = new $item_iterator(self).next()
571
$DictDict.__delitem__(self,itm[0])
572
return _b_.tuple(itm)
573
}catch(err) {
574
if (err.__name__ == "StopIteration") {
575
throw KeyError("'popitem(): dictionary is empty'")
576
}
577
}
Sep 5, 2014
578
}
579
Nov 21, 2015
580
$DictDict.setdefault = function(){
581
582
var $ = $B.args('setdefault', 3, {self:null, key: null, _default:null},
583
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
Nov 21, 2015
584
self=$.self, key=$.key, _default=$._default
585
Sep 5, 2014
586
try{return $DictDict.__getitem__(self,key)}
587
catch(err){
588
if(_default===undefined) _default=None
589
$DictDict.__setitem__(self,key,_default)
590
return _default
591
}
592
}
593
594
$DictDict.update = function(self){
Nov 21, 2015
595
596
var $ = $B.args('update',1,{'self':null},['self'],arguments,{},'args','kw'),
597
self=$.self, args=$.args, kw=$.kw
598
599
if(args.length>0) {
600
var o=args[0]
601
if (isinstance(o,dict)){
602
$copy_dict(self, o)
603
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
604
var _keys=_b_.list(getattr(o, 'keys')())
605
var si=$DictDict.__setitem__
606
var i=_keys.length
607
while(i--) {
608
//for (var i=0; i < _keys.length; i++) {
609
var _value = getattr(o, '__getitem__')(_keys[i])
610
si(self, _keys[i], _value)
Sep 5, 2014
613
}
Sep 5, 2014
616
}
617
Nov 21, 2015
618
var $dict_valuesDict = $B.$iterator_class('dict_values')
619
620
$DictDict.values = function(self){
621
if (arguments.length > 1) {
622
var _len=arguments.length - 1
623
var _msg="values() takes no arguments ("+_len+" given)"
624
throw _b_.TypeError(_msg)
625
}
626
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
627
}
628
629
function dict(args, second){
631
var res = {__class__:$DictDict,
632
$numeric_dict : {},
633
$object_dict : {},
634
$string_dict : {},
635
$str_hash: {},
636
length: 0
637
}
638
639
if(args===undefined){return res}
640
641
if(second===undefined){
642
if(Array.isArray(args)){
643
// Form "dict([[key1, value1], [key2,value2], ...])"
644
var i = -1, stop = args.length-1
645
var si = $DictDict.__setitem__
646
while(i++<stop){
647
var item=args[i]
648
switch(typeof item[0]) {
649
case 'string':
650
res.$string_dict[item[0]]=item[1]
651
res.$str_hash[str_hash(item[0])]=item[0]
652
break;
653
case 'number':
654
res.$numeric_dict[item[0]]=item[1]
655
break
656
default:
657
si(res, item[0], item[1])
658
break
659
}
660
}
661
return res
662
}else if(args.$nat=='kw'){
663
// Form dict(k1=v1, k2=v2...)
664
var kw = args['kw']
665
for(var attr in kw){
666
switch(typeof attr) {
667
case 'string':
668
res.$string_dict[attr]=kw[attr]
669
res.$str_hash[str_hash(attr)]=attr
670
break;
671
case 'number':
672
res.$numeric_dict[attr]=kw[attr]
673
break
674
default:
675
si(res, attr, kw[attr])
676
break
677
}
Sep 5, 2014
683
// apply __init__ with arguments of dict()
684
var _args = [res], pos=1
685
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
686
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
687
return res
688
}
Sep 5, 2014
690
dict.__class__ = $B.$factory
691
dict.$dict = $DictDict
692
$DictDict.$factory = dict
693
$DictDict.__new__ = $B.$__new__(dict)
694
695
_b_.dict = dict
697
$B.set_func_names($DictDict)
698
699
// following are used for faster access elsewhere
700
$B.$dict_iterator = function(d) { return new $item_generator(d) }
701
$B.$dict_length = $DictDict.__len__
702
$B.$dict_getitem = $DictDict.__getitem__
703
$B.$dict_get = $DictDict.get
704
$B.$dict_set = $DictDict.__setitem__
705
$B.$dict_contains = $DictDict.__contains__
706
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
707
$B.$copy_dict = $copy_dict // copy from right to left
708
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
709
711
// Class for attribute __dict__ of classes
712
var mappingproxyDict = {
713
__class__ : $B.$type,
714
__name__ : "mappingproxy"
715
}
716
mappingproxyDict.__mro__ = [_b_.object.$dict]
717
718
mappingproxyDict.__setitem__ = function(){
719
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
720
}
721
723
function mappingproxy(obj){
724
var res = obj_dict(obj)
725
res.__class__ = mappingproxyDict
726
return res
727
}
728
mappingproxy.__class__ = $B.$factory
729
mappingproxy.$dict = mappingproxyDict
730
mappingproxyDict.$factory = mappingproxy
731
$B.mappingproxy = mappingproxy
732
733
$B.obj_dict = function(obj){
734
var res = dict()
735
res.$jsobj = obj
736
return res
737
}
738
Sep 5, 2014
739
})(__BRYTHON__)