Skip to content
Permalink
Newer
Older
100644 714 lines (601 sloc) 19.8 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
var $iterator_wrapper = function(items,klass){
95
var res = {
96
__class__:klass,
97
__iter__:function(){items.iter.i=0; return res},
98
__len__:function(){return items.length()},
99
__next__:function(){
100
return items.next()
101
},
102
__repr__:function(){return klass.__name__+'('+ new $item_generator(items).as_list().join(',') + ')'},
103
}
104
res.__str__ = res.toString = res.__repr__
105
return res
106
}
107
108
$DictDict.__bool__ = function () {
Nov 21, 2015
109
var $=$B.args('__bool__',1,{self:null},['self'],arguments,{},null,null)
110
return $DictDict.__len__($.self) > 0
113
$DictDict.__contains__ = function(){
Nov 21, 2015
114
115
var $ = $B.args('__contains__', 2, {self:null, item:null},
116
['self', 'item'], arguments, {}, null, null),
117
self=$.self, item=$.item
Nov 21, 2015
118
Sep 5, 2014
119
if(self.$jsobj) return self.$jsobj[item]!==undefined
Nov 21, 2015
120
121
switch(typeof item) {
122
case 'string':
123
return self.$string_dict[item] !==undefined
124
case 'number':
125
return self.$numeric_dict[item] !==undefined
127
128
var _key=hash(item)
129
if (self.$str_hash[_key]!==undefined &&
130
_b_.getattr(item,'__eq__')(self.$str_hash[_key])){return true}
131
if (self.$numeric_dict[_key]!==undefined &&
132
_b_.getattr(item,'__eq__')(_key)){return true}
133
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
134
// If the key is an object, its hash must be in the dict keys but the
135
// key itself must compare equal to the key associated with the hash
136
// For instance :
137
//
138
// class X:
139
// def __hash__(self): return hash('u')
140
//
141
// a = {'u': 'a', X(): 'b'}
142
// assert set(a.values())=={'a', 'b'}
143
// assert not X() in a
144
145
var _eq = getattr(item, '__eq__')
Nov 21, 2015
146
if(_eq(self.$object_dict[_key][0])){return true}
147
}
148
return false
Sep 5, 2014
149
}
150
Nov 21, 2015
151
$DictDict.__delitem__ = function(){
152
153
var $ = $B.args('__eq__', 2, {self:null, arg:null},
154
['self', 'arg'], arguments, {}, null, null),
155
self=$.self, arg=$.arg
156
157
if(self.$jsobj){
158
if(self.$jsobj[arg]===undefined){throw KeyError(arg)}
159
delete self.$jsobj[arg]
162
switch(typeof arg) {
163
case 'string':
164
if (self.$string_dict[arg] === undefined) throw KeyError(_b_.str(arg))
165
delete self.$string_dict[arg]
166
delete self.$str_hash[str_hash(arg)]
168
case 'number':
169
if (self.$numeric_dict[arg] === undefined) throw KeyError(_b_.str(arg))
170
delete self.$numeric_dict[arg]
173
// go with defaults
175
var _key=hash(arg)
Nov 21, 2015
176
177
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
178
delete self.$object_dict[_key]
180
181
if(self.$jsobj) delete self.$jsobj[arg]
Sep 5, 2014
183
}
184
Nov 21, 2015
185
$DictDict.__eq__ = function(){
186
var $ = $B.args('__eq__', 2, {self:null, other:null},
187
['self', 'other'], arguments, {}, null, null),
188
self=$.self, other=$.other
189
190
if(!isinstance(other,dict)) return false
192
if ($DictDict.__len__(self) != $DictDict.__len__(other)){return false}
Nov 21, 2015
194
if((self.$numeric_dict.length!=other.$numeric_dict.length) ||
195
(self.$string_dict.length!=other.$string_dict.length) ||
196
(self.$object_dict.length!=other.$object_dict.length)){
197
return false
Nov 21, 2015
199
for(var k in self.$numeric_dict){
200
if(!_b_.getattr(other.$numeric_dict[k],'__eq__')(self.$numeric_dict[k])){
201
return false
202
}
203
}
204
for(var k in self.$string_dict){
205
if(!_b_.getattr(other.$string_dict[k],'__eq__')(self.$string_dict[k])){
206
return false
207
}
208
}
209
for(var k in self.$object_dict){
210
if(!_b_.getattr(other.$object_dict[k][1],'__eq__')(self.$object_dict[k][1])){
211
return false
212
}
213
}
214
Nov 21, 2015
216
Sep 5, 2014
217
}
218
Nov 21, 2015
219
$DictDict.__getitem__ = function(){
220
var $ = $B.args('__getitem__', 2, {self:null, arg:null},
221
['self', 'arg'], arguments, {}, null, null),
222
self=$.self, arg=$.arg
223
224
if(self.$jsobj){
225
if(self.$jsobj[arg]===undefined){return None}
226
return self.$jsobj[arg]
227
}
230
switch(typeof arg) {
231
case 'string':
232
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
233
break
234
case 'number':
235
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
238
// since the key is more complex use 'default' method of getting item
239
240
var _key = _b_.hash(arg),
241
_eq = _b_.getattr(arg, '__eq__')
242
243
var sk = self.$str_hash[_key]
244
if (sk!==undefined && _eq(sk)){
245
return self.$string_dict[sk]
246
}
247
if (self.$numeric_dict[_key]!==undefined && _eq(_key)){
248
return self.$numeric_dict[_key]
250
251
var obj_ref = self.$object_dict[_key]
252
if(obj_ref!==undefined){
253
// An object with the same hash is already stored
254
// Lookup should fail if equality raises an exception
255
_eq(self.$object_dict[_key][0])
Nov 21, 2015
256
return self.$object_dict[_key][1]
258
if(self.__class__!==$DictDict){
259
try{
260
var missing_method = getattr(self.__class__.$factory, '__missing__')
261
return missing_method(self, arg)
262
}catch(err){}
263
}
Sep 5, 2014
264
throw KeyError(_b_.str(arg))
265
}
266
267
$DictDict.__hash__ = None
Sep 5, 2014
268
269
$DictDict.__init__ = function(self){
270
var args = [], pos=0
271
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
274
switch(args.length) {
275
case 0:
276
return
277
case 1:
Sep 5, 2014
278
var obj = args[0]
279
if(Array.isArray(obj)){
280
var i = obj.length
281
var si = $DictDict.__setitem__
282
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
284
}else if(isinstance(obj,dict)){
Sep 5, 2014
287
}
Sep 5, 2014
289
if(obj.__class__===$B.JSObject.$dict){
290
// convert a JSObject into a Python dictionary
291
var si = $DictDict.__setitem__
292
for(var attr in obj.js) si(self,attr,obj.js[attr])
293
294
// Attribute $jsobj is used to update the original JS object
295
// when the dictionary is modified
Sep 5, 2014
298
}
301
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
302
var args = $ns['args']
303
var kw = $ns['kw']
Sep 5, 2014
306
if(isinstance(args[0],dict)){
Sep 5, 2014
309
}
Sep 5, 2014
311
// format dict([(k1,v1),(k2,v2)...])
312
313
if(Array.isArray(args[0])){
314
var src = args[0]
316
var si=$DictDict.__setitem__
317
while(i-->0) si(self, src[i-1][0], src[i-1][1])
318
}else{
319
var iterable = iter(args[0])
320
while(1){
321
try{
322
var elt = next(iterable)
323
var key = getattr(elt,'__getitem__')(0)
324
var value = getattr(elt,'__getitem__')(1)
325
$DictDict.__setitem__(self, key, value)
326
}catch(err){
327
if(err.__name__==='StopIteration'){break}
Sep 5, 2014
330
}
331
}
333
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
335
}
336
337
var $dict_iterator = $B.$iterator_class('dict iterator')
338
$DictDict.__iter__ = function(self) {
339
return $DictDict.keys(self)
Sep 5, 2014
340
}
341
342
$DictDict.__len__ = function(self) {
343
var _count=0
344
345
if(self.$jsobj){
346
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
347
return _count
348
}
350
for (var k in self.$numeric_dict) _count++
351
for (var k in self.$string_dict) _count++
352
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
354
return _count
Sep 5, 2014
356
357
$DictDict.__mro__ = [$ObjectDict]
Sep 5, 2014
358
359
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
360
361
$DictDict.__next__ = function(self){
363
self.$iter = new $item_generator(self)
364
}
365
try {
366
return self.$iter.next()
367
} catch (err) {
368
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
369
}
370
}
371
372
$DictDict.__repr__ = function(self){
373
if(self===undefined) return "<class 'dict'>"
374
if(self.$jsobj){ // wrapper around Javascript object
375
var res = []
376
for(var attr in self.$jsobj){
377
if(attr.charAt(0)=='$' || attr=='__class__'){continue}
Nov 4, 2015
378
else{
379
try{
380
res.push("'"+attr+"': "+_b_.repr(self.$jsobj[attr]))
381
}catch(err){
382
// FIX ME
383
}
384
}
385
}
386
return '{'+res.join(', ')+'}'
387
}
388
var res=[],
389
pos=0,
390
items = new $item_generator(self).as_list()
391
for (var i=0; i < items.length; i++) {
392
var itm = items[i]
393
if(itm[1]===self){res[pos++]=repr(itm[0])+': {...}'}
394
else{res[pos++]=repr(itm[0])+': '+repr(itm[1])}
Sep 5, 2014
395
}
396
return '{'+ res.join(', ') +'}'
Sep 5, 2014
397
}
398
399
$DictDict.__setitem__ = function(self,key,value){
Nov 21, 2015
401
var $ = $B.args('__setitem__', 3, {self:null, key:null, value:null},
402
['self', 'key', 'value'], arguments, {}, null, null),
403
self=$.self, key=$.key, value=$.value
404
405
if(self.$jsobj){self.$jsobj[key]=value;return}
406
407
switch(typeof key) {
408
case 'string':
409
self.$string_dict[key]=value
410
self.$str_hash[str_hash(key)]=key
412
case 'number':
413
self.$numeric_dict[key]=value
417
// if we got here the key is more complex, use default method
419
var _key=hash(key)
420
var _eq=getattr(key, '__eq__')
422
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
423
self.$numeric_dict[_key] = value
425
}
426
var sk = self.$str_hash[_key]
427
if(sk!==undefined && _eq(sk)){
428
self.$string_dict[sk] = value
430
}
431
432
var obj_ref = self.$object_dict[_key]
433
if(obj_ref!==undefined){
434
// An object with the same hash is already stored
435
// Lookup should fail if equality raises an exception
436
_eq(self.$object_dict[_key][0])
437
}
438
self.$object_dict[_key] = [key, value]
Sep 5, 2014
440
}
441
442
$DictDict.__str__ = $DictDict.__repr__
443
444
// add "reflected" methods
445
$B.make_rmethods($DictDict)
446
447
$DictDict.clear = function(){
Sep 5, 2014
448
// Remove all items from the dictionary.
449
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
450
self = $.self
452
self.$numeric_dict={}
453
self.$string_dict={}
454
self.$str_hash={}
455
self.$object_dict={}
Sep 5, 2014
457
if(self.$jsobj) self.$jsobj={}
Sep 5, 2014
459
}
460
461
$DictDict.copy = function(self){
462
// Return a shallow copy of the dictionary
463
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
464
self = $.self,
465
res = _b_.dict()
Sep 5, 2014
467
return res
468
}
469
Nov 21, 2015
470
$DictDict.fromkeys = function(){
471
472
var $ = $B.args('fromkeys', 3, {cls:null, keys:null, value:null},
473
['cls', 'keys', 'value'], arguments, {value:_b_.None}, null, null),
Nov 21, 2015
474
keys=$.keys, value=$.value
Sep 5, 2014
476
// class method
Sep 5, 2014
478
var keys_iter = _b_.iter(keys)
479
while(1){
480
try{
481
var key = _b_.next(keys_iter)
482
$DictDict.__setitem__(res,key,value)
483
}catch(err){
484
if($B.is_exc(err,[_b_.StopIteration])){
485
return res
486
}
487
throw err
488
}
489
}
490
}
491
$DictDict.fromkeys.$type = 'classmethod'
Sep 5, 2014
492
Nov 21, 2015
493
$DictDict.get = function(){
494
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
495
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
497
try{return $DictDict.__getitem__($.self, $.key)}
498
catch(err){
499
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
500
else{throw err}
501
}
502
}
503
504
var $dict_itemsDict = $B.$iterator_class('dict_items')
505
506
$DictDict.items = function(self){
507
if (arguments.length > 1) {
508
var _len=arguments.length - 1
509
var _msg="items() takes no arguments ("+_len+" given)"
510
throw _b_.TypeError(_msg)
511
}
512
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
513
}
514
Nov 21, 2015
515
var $dict_keysDict = $B.$iterator_class('dict_keys')
516
517
$DictDict.keys = function(self){
518
if (arguments.length > 1) {
519
var _len=arguments.length - 1
520
var _msg="keys() takes no arguments ("+_len+" given)"
521
throw _b_.TypeError(_msg)
522
}
523
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
524
}
525
526
$DictDict.pop = function(){
527
528
var $ = $B.args('pop', 3, {self:null, key: null, _default:null},
529
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
530
self=$.self, key=$.key, _default=$._default
531
Sep 5, 2014
532
try{
533
var res = $DictDict.__getitem__(self,key)
534
$DictDict.__delitem__(self,key)
535
return res
536
}catch(err){
537
if(err.__name__==='KeyError'){
538
if(_default!==undefined) return _default
539
throw err
540
}
541
throw err
542
}
543
}
544
545
$DictDict.popitem = function(self){
546
try{
547
var itm = new $item_iterator(self).next()
548
$DictDict.__delitem__(self,itm[0])
549
return _b_.tuple(itm)
550
}catch(err) {
551
if (err.__name__ == "StopIteration") {
552
throw KeyError("'popitem(): dictionary is empty'")
553
}
554
}
Sep 5, 2014
555
}
556
Nov 21, 2015
557
$DictDict.setdefault = function(){
558
559
var $ = $B.args('setdefault', 3, {self:null, key: null, _default:null},
560
['self', 'key', '_default'], arguments, {}, null, null),
561
self=$.self, key=$.key, _default=$._default
562
Sep 5, 2014
563
try{return $DictDict.__getitem__(self,key)}
564
catch(err){
565
if(_default===undefined) _default=None
566
$DictDict.__setitem__(self,key,_default)
567
return _default
568
}
569
}
570
571
$DictDict.update = function(self){
Nov 21, 2015
572
573
var $ = $B.args('update',1,{'self':null},['self'],arguments,{},'args','kw'),
574
self=$.self, args=$.args, kw=$.kw
575
576
if(args.length>0) {
577
var o=args[0]
578
if (isinstance(o,dict)){
579
$copy_dict(self, o)
580
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
581
var _keys=_b_.list(getattr(o, 'keys')())
582
var si=$DictDict.__setitem__
583
var i=_keys.length
584
while(i--) {
585
//for (var i=0; i < _keys.length; i++) {
586
var _value = getattr(o, '__getitem__')(_keys[i])
587
si(self, _keys[i], _value)
Sep 5, 2014
590
}
Sep 5, 2014
593
}
594
Nov 21, 2015
595
var $dict_valuesDict = $B.$iterator_class('dict_values')
596
597
$DictDict.values = function(self){
598
if (arguments.length > 1) {
599
var _len=arguments.length - 1
600
var _msg="values() takes no arguments ("+_len+" given)"
601
throw _b_.TypeError(_msg)
602
}
603
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
604
}
605
606
function dict(args, second){
608
var res = {__class__:$DictDict,
609
$numeric_dict : {},
610
$object_dict : {},
611
$string_dict : {},
612
$str_hash: {},
613
length: 0
614
}
615
616
if(args===undefined){return res}
617
618
if(second===undefined){
619
if(Array.isArray(args)){
620
// Form "dict([[key1, value1], [key2,value2], ...])"
621
var i = -1, stop = args.length-1
622
var si = $DictDict.__setitem__
623
while(i++<stop){
624
var item=args[i]
625
switch(typeof item[0]) {
626
case 'string':
627
res.$string_dict[item[0]]=item[1]
628
res.$str_hash[str_hash(item[0])]=item[0]
629
break;
630
case 'number':
631
res.$numeric_dict[item[0]]=item[1]
632
break
633
default:
634
si(res, item[0], item[1])
635
break
636
}
637
}
638
return res
639
}else if(args.$nat=='kw'){
640
// Form dict(k1=v1, k2=v2...)
641
var kw = args['kw']
642
for(var attr in kw){
643
switch(typeof attr) {
644
case 'string':
645
res.$string_dict[attr]=kw[attr]
646
res.$str_hash[str_hash(attr)]=attr
647
break;
648
case 'number':
649
res.$numeric_dict[attr]=kw[attr]
650
break
651
default:
652
si(res, attr, kw[attr])
653
break
654
}
Sep 5, 2014
660
// apply __init__ with arguments of dict()
661
var _args = [res], pos=1
662
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
663
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
664
return res
665
}
Sep 5, 2014
667
dict.__class__ = $B.$factory
668
dict.$dict = $DictDict
669
$DictDict.$factory = dict
670
$DictDict.__new__ = $B.$__new__(dict)
671
672
_b_.dict = dict
674
// following are used for faster access elsewhere
675
$B.$dict_iterator = function(d) { return new $item_generator(d) }
676
$B.$dict_length = $DictDict.__len__
677
$B.$dict_getitem = $DictDict.__getitem__
678
$B.$dict_get = $DictDict.get
679
$B.$dict_set = $DictDict.__setitem__
680
$B.$dict_contains = $DictDict.__contains__
681
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
682
$B.$copy_dict = $copy_dict // copy from right to left
683
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
684
686
// Class for attribute __dict__ of classes
687
var mappingproxyDict = {
688
__class__ : $B.$type,
689
__name__ : "mappingproxy"
690
}
691
mappingproxyDict.__mro__ = [_b_.object.$dict]
692
693
mappingproxyDict.__setitem__ = function(){
694
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
695
}
696
698
function mappingproxy(obj){
699
var res = obj_dict(obj)
700
res.__class__ = mappingproxyDict
701
return res
702
}
703
mappingproxy.__class__ = $B.$factory
704
mappingproxy.$dict = mappingproxyDict
705
mappingproxyDict.$factory = mappingproxy
706
$B.mappingproxy = mappingproxy
707
708
$B.obj_dict = function(obj){
709
var res = dict()
710
res.$jsobj = obj
711
return res
712
}
713
Sep 5, 2014
714
})(__BRYTHON__)