Skip to content
Permalink
Newer
Older
100644 683 lines (572 sloc) 18.9 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])
92
}
93
94
$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
Nov 21, 2015
108
$DictDict.__bool__ = function (self) {
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
221
var $ = $B.args('__getitem__', 2, {self:null, arg:null},
222
['self', 'arg'], arguments, {}, null, null),
223
self=$.self, arg=$.arg
224
225
if(self.$jsobj){
226
if(self.$jsobj[arg]===undefined){return None}
227
return self.$jsobj[arg]
228
}
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=hash(arg)
241
var sk = self.$str_hash[_key]
242
if (sk!==undefined && _b_.getattr(arg,'__eq__')(sk)){
243
return self.$string_dict[sk]
244
}
245
if (self.$numeric_dict[_key]!==undefined &&
246
_b_.getattr(arg,'__eq__')(_key)){
247
return self.$numeric_dict[_key]
248
}
249
if (self.$object_dict[_key] !== undefined) {
Nov 21, 2015
250
return self.$object_dict[_key][1]
252
253
if(hasattr(self, '__missing__')) return getattr(self, '__missing__')(arg)
254
Sep 5, 2014
255
throw KeyError(_b_.str(arg))
256
}
257
258
$DictDict.__hash__ = function(self) {
259
if (self === undefined) {
260
return $DictDict.__hashvalue__ || $B.$py_next_hash-- // for hash of dict type (not instance of dict)
261
}
262
throw _b_.TypeError("unhashable type: 'dict'");
263
}
Sep 5, 2014
264
265
$DictDict.__init__ = function(self){
266
var args = [], pos=0
267
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
270
switch(args.length) {
271
case 0:
272
return
273
case 1:
Sep 5, 2014
274
var obj = args[0]
275
if(Array.isArray(obj)){
276
var i = obj.length
277
var si = $DictDict.__setitem__
278
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
280
}else if(isinstance(obj,dict)){
Sep 5, 2014
283
}
Sep 5, 2014
285
if(obj.__class__===$B.JSObject.$dict){
286
// convert a JSObject into a Python dictionary
287
var si = $DictDict.__setitem__
288
for(var attr in obj.js) si(self,attr,obj.js[attr])
289
290
// Attribute $jsobj is used to update the original JS object
291
// when the dictionary is modified
Sep 5, 2014
294
}
297
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
298
var args = $ns['args']
299
var kw = $ns['kw']
Sep 5, 2014
302
if(isinstance(args[0],dict)){
Sep 5, 2014
305
}
Sep 5, 2014
307
// format dict([(k1,v1),(k2,v2)...])
308
309
if(Array.isArray(args[0])){
310
var src = args[0]
312
var si=$DictDict.__setitem__
313
while(i-->0) si(self, src[i-1][0], src[i-1][1])
314
}else{
315
var iterable = iter(args[0])
316
while(1){
317
try{
318
var elt = next(iterable)
319
var key = getattr(elt,'__getitem__')(0)
320
var value = getattr(elt,'__getitem__')(1)
321
$DictDict.__setitem__(self, key, value)
322
}catch(err){
323
if(err.__name__==='StopIteration'){break}
Sep 5, 2014
326
}
327
}
329
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
331
}
332
333
var $dict_iterator = $B.$iterator_class('dict iterator')
334
$DictDict.__iter__ = function(self) {
335
return $DictDict.keys(self)
Sep 5, 2014
336
}
337
338
$DictDict.__len__ = function(self) {
339
var _count=0
340
341
if(self.$jsobj){
342
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
343
return _count
344
}
346
for (var k in self.$numeric_dict) _count++
347
for (var k in self.$string_dict) _count++
348
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
350
return _count
Sep 5, 2014
352
353
$DictDict.__mro__ = [$DictDict,$ObjectDict]
354
355
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
356
357
$DictDict.__next__ = function(self){
359
self.$iter = new $item_generator(self)
360
}
361
try {
362
return self.$iter.next()
363
} catch (err) {
364
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
365
}
366
}
367
368
$DictDict.__repr__ = function(self){
369
if(self===undefined) return "<class 'dict'>"
370
if(self.$jsobj){ // wrapper around Javascript object
371
var res = []
372
for(var attr in self.$jsobj){
373
if(attr.charAt(0)=='$' || attr=='__class__'){continue}
Nov 4, 2015
374
else{
375
try{
376
res.push("'"+attr+"': "+_b_.repr(self.$jsobj[attr]))
377
}catch(err){
378
// FIX ME
379
}
380
}
381
}
382
return '{'+res.join(', ')+'}'
383
}
384
var _objs=[self] // used to elimate recursion
385
var res=[], pos=0
386
var items = new $item_generator(self).as_list()
387
for (var i=0; i < items.length; i++) {
388
var itm = items[i]
389
if(itm[1]===self){res[pos++]=repr(itm[0])+': {...}'}
390
else{res[pos++]=repr(itm[0])+': '+repr(itm[1])}
Sep 5, 2014
391
}
392
return '{'+ res.join(', ') +'}'
Sep 5, 2014
393
}
394
395
$DictDict.__setitem__ = function(self,key,value){
Nov 21, 2015
397
var $ = $B.args('__setitem__', 3, {self:null, key:null, value:null},
398
['self', 'key', 'value'], arguments, {}, null, null),
399
self=$.self, key=$.key, value=$.value
400
401
if(self.$jsobj){self.$jsobj[key]=value;return}
402
403
switch(typeof key) {
404
case 'string':
405
self.$string_dict[key]=value
406
self.$str_hash[str_hash(key)]=key
408
case 'number':
409
self.$numeric_dict[key]=value
413
// if we got here the key is more complex, use default method
415
var _key=hash(key)
416
var _eq=getattr(key, '__eq__')
417
418
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
419
self.$numeric_dict[_key] = value
421
}
422
var sk = self.$str_hash[_key]
423
if(sk!==undefined && _eq(sk)){
424
self.$string_dict[sk] = value
426
}
427
Nov 21, 2015
428
self.$object_dict[_key]=[key, value]
Sep 5, 2014
430
}
431
432
$DictDict.__str__ = $DictDict.__repr__
433
434
// add "reflected" methods
435
$B.make_rmethods($DictDict)
436
437
$DictDict.clear = function(){
Sep 5, 2014
438
// Remove all items from the dictionary.
439
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
440
self = $.self
442
self.$numeric_dict={}
443
self.$string_dict={}
444
self.$str_hash={}
445
self.$object_dict={}
Sep 5, 2014
447
if(self.$jsobj) self.$jsobj={}
Sep 5, 2014
449
}
450
451
$DictDict.copy = function(self){
452
// Return a shallow copy of the dictionary
453
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
454
self = $.self,
455
res = _b_.dict()
Sep 5, 2014
457
return res
458
}
459
Nov 21, 2015
460
$DictDict.fromkeys = function(){
461
462
var $ = $B.args('fromkeys', 3, {cls:null, keys:null, value:null},
463
['cls', 'keys', 'value'], arguments, {value:_b_.None}, null, null),
Nov 21, 2015
464
keys=$.keys, value=$.value
465
Sep 5, 2014
466
// class method
467
var res = dict()
468
var keys_iter = _b_.iter(keys)
469
while(1){
470
try{
471
var key = _b_.next(keys_iter)
472
$DictDict.__setitem__(res,key,value)
473
}catch(err){
474
if($B.is_exc(err,[_b_.StopIteration])){
475
return res
476
}
477
throw err
478
}
479
}
480
}
481
$DictDict.fromkeys.$type = 'classmethod'
Sep 5, 2014
482
Nov 21, 2015
483
$DictDict.get = function(){
484
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
485
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
487
try{return $DictDict.__getitem__($.self, $.key)}
488
catch(err){
489
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
490
else{throw err}
491
}
492
}
493
494
var $dict_itemsDict = $B.$iterator_class('dict_items')
495
496
$DictDict.items = function(self){
497
if (arguments.length > 1) {
498
var _len=arguments.length - 1
499
var _msg="items() takes no arguments ("+_len+" given)"
500
throw _b_.TypeError(_msg)
501
}
502
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
503
}
504
Nov 21, 2015
505
var $dict_keysDict = $B.$iterator_class('dict_keys')
506
507
$DictDict.keys = function(self){
508
if (arguments.length > 1) {
509
var _len=arguments.length - 1
510
var _msg="keys() takes no arguments ("+_len+" given)"
511
throw _b_.TypeError(_msg)
512
}
513
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
514
}
515
516
$DictDict.pop = function(){
517
518
var $ = $B.args('pop', 3, {self:null, key: null, _default:null},
519
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
520
self=$.self, key=$.key, _default=$._default
521
Sep 5, 2014
522
try{
523
var res = $DictDict.__getitem__(self,key)
524
$DictDict.__delitem__(self,key)
525
return res
526
}catch(err){
527
if(err.__name__==='KeyError'){
528
if(_default!==undefined) return _default
529
throw err
530
}
531
throw err
532
}
533
}
534
535
$DictDict.popitem = function(self){
536
try{
537
var itm = new $item_iterator(self).next()
538
$DictDict.__delitem__(self,itm[0])
539
return _b_.tuple(itm)
540
}catch(err) {
541
if (err.__name__ == "StopIteration") {
542
throw KeyError("'popitem(): dictionary is empty'")
543
}
544
}
Sep 5, 2014
545
}
546
Nov 21, 2015
547
$DictDict.setdefault = function(){
548
549
var $ = $B.args('setdefault', 3, {self:null, key: null, _default:null},
550
['self', 'key', '_default'], arguments, {}, null, null),
551
self=$.self, key=$.key, _default=$._default
552
Sep 5, 2014
553
try{return $DictDict.__getitem__(self,key)}
554
catch(err){
555
if(_default===undefined) _default=None
556
$DictDict.__setitem__(self,key,_default)
557
return _default
558
}
559
}
560
561
$DictDict.update = function(self){
Nov 21, 2015
562
563
var $ = $B.args('update',1,{'self':null},['self'],arguments,{},'args','kw'),
564
self=$.self, args=$.args, kw=$.kw
565
566
if(args.length>0) {
567
var o=args[0]
568
if (isinstance(o,dict)){
569
$copy_dict(self, o)
570
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
571
var _keys=_b_.list(getattr(o, 'keys')())
572
var si=$DictDict.__setitem__
573
var i=_keys.length
574
while(i--) {
575
//for (var i=0; i < _keys.length; i++) {
576
var _value = getattr(o, '__getitem__')(_keys[i])
577
si(self, _keys[i], _value)
Sep 5, 2014
580
}
Sep 5, 2014
583
}
584
Nov 21, 2015
585
var $dict_valuesDict = $B.$iterator_class('dict_values')
586
587
$DictDict.values = function(self){
588
if (arguments.length > 1) {
589
var _len=arguments.length - 1
590
var _msg="values() takes no arguments ("+_len+" given)"
591
throw _b_.TypeError(_msg)
592
}
593
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
594
}
595
596
function dict(args, second){
598
if(second===undefined && Array.isArray(args)){
599
// Form "dict([[key1, value1], [key2,value2], ...])"
600
var res = {__class__:$DictDict,
601
$numeric_dict : {},
602
$object_dict : {},
603
$string_dict : {},
604
$str_hash: {},
607
var i = -1, stop = args.length-1
608
var si = $DictDict.__setitem__
609
while(i++<stop){
610
var item=args[i]
611
switch(typeof item[0]) {
612
case 'string':
613
res.$string_dict[item[0]]=item[1]
614
res.$str_hash[str_hash(item[0])]=item[0]
615
break;
616
case 'number':
617
res.$numeric_dict[item[0]]=item[1]
618
break
619
default:
620
si(res, item[0], item[1])
624
return res
625
}
626
Sep 5, 2014
627
// apply __init__ with arguments of dict()
628
var res = {__class__:$DictDict}
629
$DictDict.clear(res)
630
var _args = [res], pos=1
631
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
632
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
633
return res
634
}
Sep 5, 2014
636
dict.__class__ = $B.$factory
637
dict.$dict = $DictDict
638
$DictDict.$factory = dict
639
$DictDict.__new__ = $B.$__new__(dict)
640
641
_b_.dict = dict
643
// following are used for faster access elsewhere
644
$B.$dict_iterator = function(d) { return new $item_generator(d) }
645
$B.$dict_length = $DictDict.__len__
646
$B.$dict_getitem = $DictDict.__getitem__
647
$B.$dict_get = $DictDict.get
648
$B.$dict_set = $DictDict.__setitem__
649
$B.$dict_contains = $DictDict.__contains__
650
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
651
$B.$copy_dict = $copy_dict // copy from right to left
652
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
653
655
// Class for attribute __dict__ of classes
656
var mappingproxyDict = {
657
__class__ : $B.$type,
658
__name__ : "mappingproxy"
659
}
660
mappingproxyDict.__mro__ = [mappingproxyDict, _b_.object.$dict]
661
662
mappingproxyDict.__setitem__ = function(){
663
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
664
}
665
667
function mappingproxy(obj){
668
var res = obj_dict(obj)
669
res.__class__ = mappingproxyDict
670
return res
671
}
672
mappingproxy.__class__ = $B.$factory
673
mappingproxy.$dict = mappingproxyDict
674
mappingproxyDict.$factory = mappingproxy
675
$B.mappingproxy = mappingproxy
676
677
$B.obj_dict = function(obj){
678
var res = dict()
679
res.$jsobj = obj
680
return res
681
}
682
Sep 5, 2014
683
})(__BRYTHON__)