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