Skip to content
Permalink
Newer
Older
100644 697 lines (588 sloc) 19.5 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
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
}
229
switch(typeof arg) {
230
case 'string':
231
if (self.$string_dict[arg] !== undefined) return self.$string_dict[arg]
232
break
233
case 'number':
234
if (self.$numeric_dict[arg] !== undefined) return self.$numeric_dict[arg]
237
// since the key is more complex use 'default' method of getting item
238
239
var _key = _b_.getattr(arg, '__hash__')(),
240
_eq = _b_.getattr(arg, '__eq__')
241
242
var sk = self.$str_hash[_key]
243
if (sk!==undefined && _eq(sk)){
244
return self.$string_dict[sk]
245
}
246
if (self.$numeric_dict[_key]!==undefined && _eq(_key)){
247
return self.$numeric_dict[_key]
249
250
var obj_ref = self.$object_dict[_key]
251
if(obj_ref!==undefined){
252
// An object with the same hash is already stored
253
// Lookup should fail if equality raises an exception
254
_eq(self.$object_dict[_key][0])
Nov 21, 2015
255
return self.$object_dict[_key][1]
257
if(self.__class__!==$DictDict){
258
try{
259
var missing_method = getattr(self.__class__.$factory, '__missing__')
260
return missing_method(self, arg)
261
}catch(err){}
262
}
Sep 5, 2014
263
throw KeyError(_b_.str(arg))
264
}
265
266
$DictDict.__hash__ = function(self) {
267
if (self === undefined) {
268
return $DictDict.__hashvalue__ || $B.$py_next_hash-- // for hash of dict type (not instance of dict)
269
}
270
throw _b_.TypeError("unhashable type: 'dict'");
271
}
Sep 5, 2014
272
273
$DictDict.__init__ = function(self){
274
var args = [], pos=0
275
for(var i=1;i<arguments.length;i++){args[pos++]=arguments[i]}
278
switch(args.length) {
279
case 0:
280
return
281
case 1:
Sep 5, 2014
282
var obj = args[0]
283
if(Array.isArray(obj)){
284
var i = obj.length
285
var si = $DictDict.__setitem__
286
while(i-->0) si(self, obj[i-1][0], obj[i-1][1])
288
}else if(isinstance(obj,dict)){
Sep 5, 2014
291
}
Sep 5, 2014
293
if(obj.__class__===$B.JSObject.$dict){
294
// convert a JSObject into a Python dictionary
295
var si = $DictDict.__setitem__
296
for(var attr in obj.js) si(self,attr,obj.js[attr])
297
298
// Attribute $jsobj is used to update the original JS object
299
// when the dictionary is modified
Sep 5, 2014
302
}
305
var $ns=$B.args('dict',0,{},[],args,{},'args','kw')
Sep 5, 2014
306
var args = $ns['args']
307
var kw = $ns['kw']
Sep 5, 2014
310
if(isinstance(args[0],dict)){
Sep 5, 2014
313
}
Sep 5, 2014
315
// format dict([(k1,v1),(k2,v2)...])
316
317
if(Array.isArray(args[0])){
318
var src = args[0]
320
var si=$DictDict.__setitem__
321
while(i-->0) si(self, src[i-1][0], src[i-1][1])
322
}else{
323
var iterable = iter(args[0])
324
while(1){
325
try{
326
var elt = next(iterable)
327
var key = getattr(elt,'__getitem__')(0)
328
var value = getattr(elt,'__getitem__')(1)
329
$DictDict.__setitem__(self, key, value)
330
}catch(err){
331
if(err.__name__==='StopIteration'){break}
Sep 5, 2014
334
}
335
}
337
if($DictDict.__len__(kw) > 0) $copy_dict(self, kw)
Sep 5, 2014
339
}
340
341
var $dict_iterator = $B.$iterator_class('dict iterator')
342
$DictDict.__iter__ = function(self) {
343
return $DictDict.keys(self)
Sep 5, 2014
344
}
345
346
$DictDict.__len__ = function(self) {
347
var _count=0
348
349
if(self.$jsobj){
350
for(var attr in self.$jsobj){if(attr.charAt(0)!='$'){_count++}}
351
return _count
352
}
354
for (var k in self.$numeric_dict) _count++
355
for (var k in self.$string_dict) _count++
356
for (var k in self.$object_dict) _count+= self.$object_dict[k].length
358
return _count
Sep 5, 2014
360
361
$DictDict.__mro__ = [$DictDict,$ObjectDict]
362
363
$DictDict.__ne__ = function(self,other){return !$DictDict.__eq__(self,other)}
364
365
$DictDict.__next__ = function(self){
367
self.$iter = new $item_generator(self)
368
}
369
try {
370
return self.$iter.next()
371
} catch (err) {
372
if (err.__name__ !== "StopIteration") { throw err }
Sep 5, 2014
373
}
374
}
375
376
$DictDict.__repr__ = function(self){
377
if(self===undefined) return "<class 'dict'>"
378
if(self.$jsobj){ // wrapper around Javascript object
379
var res = []
380
for(var attr in self.$jsobj){
381
if(attr.charAt(0)=='$' || attr=='__class__'){continue}
Nov 4, 2015
382
else{
383
try{
384
res.push("'"+attr+"': "+_b_.repr(self.$jsobj[attr]))
385
}catch(err){
386
// FIX ME
387
}
388
}
389
}
390
return '{'+res.join(', ')+'}'
391
}
392
var _objs=[self] // used to elimate recursion
393
var res=[], pos=0
394
var items = new $item_generator(self).as_list()
395
for (var i=0; i < items.length; i++) {
396
var itm = items[i]
397
if(itm[1]===self){res[pos++]=repr(itm[0])+': {...}'}
398
else{res[pos++]=repr(itm[0])+': '+repr(itm[1])}
Sep 5, 2014
399
}
400
return '{'+ res.join(', ') +'}'
Sep 5, 2014
401
}
402
403
$DictDict.__setitem__ = function(self,key,value){
Nov 21, 2015
405
var $ = $B.args('__setitem__', 3, {self:null, key:null, value:null},
406
['self', 'key', 'value'], arguments, {}, null, null),
407
self=$.self, key=$.key, value=$.value
408
409
if(self.$jsobj){self.$jsobj[key]=value;return}
410
411
switch(typeof key) {
412
case 'string':
413
self.$string_dict[key]=value
414
self.$str_hash[str_hash(key)]=key
416
case 'number':
417
self.$numeric_dict[key]=value
421
// if we got here the key is more complex, use default method
423
var _key=hash(key)
424
var _eq=getattr(key, '__eq__')
426
if(self.$numeric_dict[_key]!==undefined && _eq(_key)){
427
self.$numeric_dict[_key] = value
429
}
430
var sk = self.$str_hash[_key]
431
if(sk!==undefined && _eq(sk)){
432
self.$string_dict[sk] = value
434
}
435
436
var obj_ref = self.$object_dict[_key]
437
if(obj_ref!==undefined){
438
// An object with the same hash is already stored
439
// Lookup should fail if equality raises an exception
440
_eq(self.$object_dict[_key][0])
441
}
442
self.$object_dict[_key] = [key, value]
Sep 5, 2014
444
}
445
446
$DictDict.__str__ = $DictDict.__repr__
447
448
// add "reflected" methods
449
$B.make_rmethods($DictDict)
450
451
$DictDict.clear = function(){
Sep 5, 2014
452
// Remove all items from the dictionary.
453
var $ = $B.args('clear',1,{self:null},['self'],arguments,{},null,null),
454
self = $.self
456
self.$numeric_dict={}
457
self.$string_dict={}
458
self.$str_hash={}
459
self.$object_dict={}
Sep 5, 2014
461
if(self.$jsobj) self.$jsobj={}
Sep 5, 2014
463
}
464
465
$DictDict.copy = function(self){
466
// Return a shallow copy of the dictionary
467
var $ = $B.args('copy',1,{self:null},['self'],arguments,{},null,null),
468
self = $.self,
469
res = _b_.dict()
Sep 5, 2014
471
return res
472
}
473
Nov 21, 2015
474
$DictDict.fromkeys = function(){
475
476
var $ = $B.args('fromkeys', 3, {cls:null, keys:null, value:null},
477
['cls', 'keys', 'value'], arguments, {value:_b_.None}, null, null),
Nov 21, 2015
478
keys=$.keys, value=$.value
479
console.log('cls', $.cls, $.cls())
Sep 5, 2014
480
// class method
Sep 5, 2014
482
var keys_iter = _b_.iter(keys)
483
while(1){
484
try{
485
var key = _b_.next(keys_iter)
486
$DictDict.__setitem__(res,key,value)
487
}catch(err){
488
if($B.is_exc(err,[_b_.StopIteration])){
489
return res
490
}
491
throw err
492
}
493
}
494
}
495
$DictDict.fromkeys.$type = 'classmethod'
Sep 5, 2014
496
Nov 21, 2015
497
$DictDict.get = function(){
498
var $ = $B.args('get', 3, {self:null, key:null, _default:null},
499
['self', 'key', '_default'], arguments, {_default:$N}, null, null)
501
try{return $DictDict.__getitem__($.self, $.key)}
502
catch(err){
503
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
504
else{throw err}
505
}
506
}
507
508
var $dict_itemsDict = $B.$iterator_class('dict_items')
509
510
$DictDict.items = function(self){
511
if (arguments.length > 1) {
512
var _len=arguments.length - 1
513
var _msg="items() takes no arguments ("+_len+" given)"
514
throw _b_.TypeError(_msg)
515
}
516
return $iterator_wrapper(new $item_iterator(self), $dict_itemsDict)
517
}
518
Nov 21, 2015
519
var $dict_keysDict = $B.$iterator_class('dict_keys')
520
521
$DictDict.keys = function(self){
522
if (arguments.length > 1) {
523
var _len=arguments.length - 1
524
var _msg="keys() takes no arguments ("+_len+" given)"
525
throw _b_.TypeError(_msg)
526
}
527
return $iterator_wrapper(new $key_iterator(self),$dict_keysDict)
528
}
529
530
$DictDict.pop = function(){
531
532
var $ = $B.args('pop', 3, {self:null, key: null, _default:null},
533
['self', 'key', '_default'], arguments, {_default:$N}, null, null),
534
self=$.self, key=$.key, _default=$._default
535
Sep 5, 2014
536
try{
537
var res = $DictDict.__getitem__(self,key)
538
$DictDict.__delitem__(self,key)
539
return res
540
}catch(err){
541
if(err.__name__==='KeyError'){
542
if(_default!==undefined) return _default
543
throw err
544
}
545
throw err
546
}
547
}
548
549
$DictDict.popitem = function(self){
550
try{
551
var itm = new $item_iterator(self).next()
552
$DictDict.__delitem__(self,itm[0])
553
return _b_.tuple(itm)
554
}catch(err) {
555
if (err.__name__ == "StopIteration") {
556
throw KeyError("'popitem(): dictionary is empty'")
557
}
558
}
Sep 5, 2014
559
}
560
Nov 21, 2015
561
$DictDict.setdefault = function(){
562
563
var $ = $B.args('setdefault', 3, {self:null, key: null, _default:null},
564
['self', 'key', '_default'], arguments, {}, null, null),
565
self=$.self, key=$.key, _default=$._default
566
Sep 5, 2014
567
try{return $DictDict.__getitem__(self,key)}
568
catch(err){
569
if(_default===undefined) _default=None
570
$DictDict.__setitem__(self,key,_default)
571
return _default
572
}
573
}
574
575
$DictDict.update = function(self){
Nov 21, 2015
576
577
var $ = $B.args('update',1,{'self':null},['self'],arguments,{},'args','kw'),
578
self=$.self, args=$.args, kw=$.kw
579
580
if(args.length>0) {
581
var o=args[0]
582
if (isinstance(o,dict)){
583
$copy_dict(self, o)
584
} else if (hasattr(o, '__getitem__') && hasattr(o, 'keys')) {
585
var _keys=_b_.list(getattr(o, 'keys')())
586
var si=$DictDict.__setitem__
587
var i=_keys.length
588
while(i--) {
589
//for (var i=0; i < _keys.length; i++) {
590
var _value = getattr(o, '__getitem__')(_keys[i])
591
si(self, _keys[i], _value)
Sep 5, 2014
594
}
Sep 5, 2014
597
}
598
Nov 21, 2015
599
var $dict_valuesDict = $B.$iterator_class('dict_values')
600
601
$DictDict.values = function(self){
602
if (arguments.length > 1) {
603
var _len=arguments.length - 1
604
var _msg="values() takes no arguments ("+_len+" given)"
605
throw _b_.TypeError(_msg)
606
}
607
return $iterator_wrapper(new $value_iterator(self), $dict_valuesDict)
608
}
609
610
function dict(args, second){
612
if(second===undefined && Array.isArray(args)){
613
// Form "dict([[key1, value1], [key2,value2], ...])"
614
var res = {__class__:$DictDict,
615
$numeric_dict : {},
616
$object_dict : {},
617
$string_dict : {},
618
$str_hash: {},
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])
638
return res
639
}
640
Sep 5, 2014
641
// apply __init__ with arguments of dict()
642
var res = {__class__:$DictDict}
643
$DictDict.clear(res)
644
var _args = [res], pos=1
645
for(var i=0, _len_i = arguments.length; i < _len_i;i++){_args[pos++]=arguments[i]}
646
$DictDict.__init__.apply(null,_args)
Sep 5, 2014
647
return res
648
}
Sep 5, 2014
650
dict.__class__ = $B.$factory
651
dict.$dict = $DictDict
652
$DictDict.$factory = dict
653
$DictDict.__new__ = $B.$__new__(dict)
654
655
_b_.dict = dict
657
// following are used for faster access elsewhere
658
$B.$dict_iterator = function(d) { return new $item_generator(d) }
659
$B.$dict_length = $DictDict.__len__
660
$B.$dict_getitem = $DictDict.__getitem__
661
$B.$dict_get = $DictDict.get
662
$B.$dict_set = $DictDict.__setitem__
663
$B.$dict_contains = $DictDict.__contains__
664
$B.$dict_items = function(d) { return new $item_generator(d).as_list() }
665
$B.$copy_dict = $copy_dict // copy from right to left
666
$B.$dict_get_copy = $DictDict.copy // return a shallow copy
667
669
// Class for attribute __dict__ of classes
670
var mappingproxyDict = {
671
__class__ : $B.$type,
672
__name__ : "mappingproxy"
673
}
674
mappingproxyDict.__mro__ = [mappingproxyDict, _b_.object.$dict]
675
676
mappingproxyDict.__setitem__ = function(){
677
throw _b_.TypeError("'mappingproxy' object does not support item assignment")
678
}
679
681
function mappingproxy(obj){
682
var res = obj_dict(obj)
683
res.__class__ = mappingproxyDict
684
return res
685
}
686
mappingproxy.__class__ = $B.$factory
687
mappingproxy.$dict = mappingproxyDict
688
mappingproxyDict.$factory = mappingproxy
689
$B.mappingproxy = mappingproxy
690
691
$B.obj_dict = function(obj){
692
var res = dict()
693
res.$jsobj = obj
694
return res
695
}
696
Sep 5, 2014
697
})(__BRYTHON__)