Skip to content
Permalink
Newer
Older
100644 1087 lines (971 sloc) 31.8 KB
Sep 5, 2014
1
;(function($B){
2
3
/*
4
Implementation of Python dictionaries
5
6
We can't use Javascript's Map here, because the behaviour is not exactly the
7
same (eg with keys that are instances of classes with a __hash__ method...)
8
and because Map is much slower than regular Javascript objects.
9
10
A Python dictionary is implemented as a Javascript objects with these
11
attributes:
12
. $version: an integer with an initial value of 0, incremented at each
13
insertion
14
. $numeric_dict: for keys of type int
15
. $string_dict and $str_hash: for keys of type str
16
. $object_dict: for keys of other types
17
18
The value associated to a key in $numeric_dict and $string_dict is a pair
19
[value, rank] where "value" is the value associated with the key and "rank"
20
is the value of the dict attribute $version when the pair is inserted. This
21
is required to keep track of the insertion order, mandatory since Python 3.7.
22
23
For keys that are not str or int, their hash value is computed. Since several
24
keys with the same hash can be stored in a dictionary, $object_dict[hash] is a
25
list of [key, [value, rank]] lists.
26
*/
27
28
var bltns = $B.InjectBuiltins()
29
eval(bltns)
31
var str_hash = _b_.str.__hash__,
Sep 5, 2014
33
34
var set_ops = ["eq", "add", "sub", "and", "or", "xor", "le", "lt", "ge", "gt"]
35
36
$B.make_view = function(name, set_like){
37
var klass = $B.make_class(name, function(items){
38
return {
39
__class__: klass,
41
counter: -1,
42
items: items,
43
len: items.length
44
}
45
})
46
47
if(set_like){
48
for(var i = 0, len = set_ops.length; i < len; i++){
49
var op = "__" + set_ops[i] + "__"
50
klass[op] = (function(op){
51
return function(self, other){
52
// compare set of items to other
53
return _b_.set[op](_b_.set.$factory(self),
54
_b_.set.$factory(other))
55
}
56
})(op)
57
}
58
}
59
klass.__iter__ = function(self){
60
var it = klass.$iterator.$factory(self.items)
61
it.len_func = self.len_func
62
return it
63
}
64
65
klass.__len__ = function(self){
66
return self.len
67
}
69
klass.__repr__ = function(self){
70
return klass.$infos.__name__ + '(' + _b_.repr(self.items) + ')'
71
}
72
73
$B.set_func_names(klass, "builtins")
74
return klass
75
}
76
77
// Special version of __next__ for iterators on dict keys / values / items.
78
// Checks that the dictionary size didn't change during iteration.
79
function dict_iterator_next(self){
80
if(self.len_func() != self.len){
81
throw _b_.RuntimeError.$factory("dictionary changed size during iteration")
82
}
83
self.counter++
84
if(self.counter < self.items.length){
85
return self.items[self.counter]
86
}
87
throw _b_.StopIteration.$factory("StopIteration")
88
}
89
Feb 11, 2018
90
var dict = {
Feb 11, 2018
91
__class__: _b_.type,
93
$infos: {
94
__module__: "builtins",
95
__name__: "dict"
96
},
Feb 11, 2018
97
$is_class: true,
98
$native: true
Sep 5, 2014
99
}
100
101
dict.$to_obj = function(d){
102
// Function applied to dictionary that only have string keys,
103
// return a Javascript objects with the kays mapped to the value,
104
// excluding the insertion rank
105
var res = {}
106
for(var key in d.$string_dict){
107
res[key] = d.$string_dict[key][0]
108
}
109
return res
110
}
111
112
function to_list(d, ix){
113
var items = [],
114
item
116
if(d.$jsobj){
Mar 7, 2018
119
if(attr.charAt(0) != "$"){
120
var val = d.$jsobj[attr]
121
if(val === undefined){val = _b_.NotImplemented}
122
else if(val === null){val = $N}
126
}else{
127
for(var k in d.$numeric_dict){
128
items.push([parseFloat(k), d.$numeric_dict[k]])
129
}
131
for(var k in d.$string_dict){items.push([k, d.$string_dict[k]])}
133
for(var k in d.$object_dict){
134
d.$object_dict[k].forEach(function(item){
135
items.push(item)
136
})
137
}
138
// sort by insertion order
139
items.sort(function(a, b){
140
return a[1][1] - b[1][1]
141
})
142
items = items.map(function(item){return [item[0], item[1][0]]})
145
if(ix !== undefined){
146
return items.map(function(item){return item[ix]})
147
}else{
148
items.__class__ = _b_.tuple
149
return items.map(function(item){
150
item.__class__ = _b_.tuple; return item}
151
)
152
}
Feb 9, 2015
154
155
$B.dict_to_list = to_list // used in py_types.js
156
157
// Special version of __next__ for iterators on dict keys / values / items.
158
// Checks that the dictionary size didn't change during iteration.
159
function dict_iterator_next(self){
160
if(self.len_func() != self.len){
161
throw _b_.RuntimeError.$factory("dictionary changed size during iteration")
162
}
163
self.counter++
164
if(self.counter < self.items.length){
165
return self.items[self.counter]
167
throw _b_.StopIteration.$factory("StopIteration")
171
var $copy_dict = function(left, right){
173
si = dict.$setitem
174
right.$version = right.$version || 0
175
var right_version = right.$version || 0
176
for(var i = 0, len = _l.length; i < len; i++){
177
si(left, _l[i][0], _l[i][1])
178
if(right.$version != right_version){
179
throw _b_.RuntimeError.$factory("dict mutated during update")
180
}
181
}
184
function rank(self, hash, key){
185
// Search if object key, with hash = hash(key), is in
186
// self.$object_dict
187
var pairs = self.$object_dict[hash]
188
if(pairs !== undefined){
189
for(var i = 0, len = pairs.length; i < len; i++){
190
if($B.rich_comp("__eq__", key, pairs[i][0])){
191
return i
192
}
193
}
194
}
195
return -1
196
}
197
Feb 11, 2018
198
dict.__bool__ = function () {
Mar 7, 2018
199
var $ = $B.args("__bool__", 1, {self: null}, ["self"],
200
arguments, {}, null, null)
Feb 11, 2018
201
return dict.__len__($.self) > 0
Feb 11, 2018
204
dict.__contains__ = function(){
Nov 21, 2015
205
206
var $ = $B.args("__contains__", 2, {self: null, key: null},
207
["self", "key"], arguments, {}, null, null),
208
self = $.self,
210
if(self.$is_namespace){key = $B.to_alias(key)} // issue 1244
211
212
if(self.$jsobj){
213
return self.$jsobj[key] !== undefined
214
}
216
switch(typeof key) {
218
return self.$string_dict[key] !== undefined
220
return self.$numeric_dict[key] !== undefined
221
}
222
223
var hash = _b_.hash(key)
224
if(self.$str_hash[hash] !== undefined &&
225
$B.rich_comp("__eq__", key, self.$str_hash[hash])){return true}
226
if(self.$numeric_dict[hash] !== undefined &&
227
$B.rich_comp("__eq__", key, hash)){return true}
228
return rank(self, hash, key) > -1
Sep 5, 2014
229
}
230
Feb 11, 2018
231
dict.__delitem__ = function(){
Nov 21, 2015
232
233
var $ = $B.args("__eq__", 2, {self: null, arg: null},
234
["self", "arg"], arguments, {}, null, null),
235
self = $.self,
Nov 21, 2015
237
238
if(self.$jsobj){
239
if(self.$jsobj[arg] === undefined){throw _b_.KeyError.$factory(arg)}
240
delete self.$jsobj[arg]
243
switch(typeof arg){
244
case "string":
245
if(self.$string_dict[arg] === undefined){
246
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
247
}
248
delete self.$string_dict[arg]
249
delete self.$str_hash[str_hash(arg)]
251
return $N
252
case "number":
253
if(self.$numeric_dict[arg] === undefined){
254
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
256
delete self.$numeric_dict[arg]
260
// go with defaults
261
262
var hash = _b_.hash(arg),
263
ix
265
if((ix = rank(self, hash, arg)) > -1){
266
self.$object_dict[hash].splice(ix, 1)
267
}else{
268
throw _b_.KeyError.$factory(_b_.str.$factory(arg))
Sep 5, 2014
273
}
274
Feb 11, 2018
275
dict.__eq__ = function(){
Mar 7, 2018
276
var $ = $B.args("__eq__", 2, {self: null, other: null},
277
["self", "other"], arguments, {}, null, null),
278
self = $.self,
279
other = $.other
281
if(! _b_.isinstance(other, dict)){return false}
283
if(self.$jsobj){self = jsobj2dict(self.$jsobj)}
284
if(other.$jsobj){other = jsobj2dict(other.$jsobj)}
285
if(dict.__len__(self) != dict.__len__(other)){
286
return false
287
}
289
if(self.$string_dict.length != other.$string_dict.length){
293
for(var k in self.$numeric_dict){
294
if(other.$numeric_dict.hasOwnProperty(k)){
295
if(!$B.rich_comp("__eq__", other.$numeric_dict[k][0],
296
self.$numeric_dict[k][0])){
297
return false
298
}
299
}else if(other.$object_dict.hasOwnProperty(k)){
300
var pairs = other.$object_dict[k],
301
flag = false
302
for(var i = 0, len = pairs.length; i < len; i++){
303
if($B.rich_comp("__eq__", k, pairs[i][0]) &&
304
$B.rich_comp("__eq__", self.$numeric_dict[k],
305
pairs[i][1])){
306
flag = true
307
break
308
}
310
if(! flag){return false}
Nov 21, 2015
313
}
314
}
315
for(var k in self.$string_dict){
316
if(!other.$string_dict.hasOwnProperty(k) ||
317
!$B.rich_comp("__eq__", other.$string_dict[k][0],
318
self.$string_dict[k][0])){
Nov 21, 2015
320
}
321
}
322
for(var hash in self.$object_dict){
323
var pairs = self.$object_dict[hash]
324
// Get all (key, value) pairs in other that have the same hash
325
var other_pairs = []
326
if(other.$numeric_dict[hash] !== undefined){
327
other_pairs.push([hash, other.$numeric_dict[hash]])
328
}
329
if(other.$object_dict[hash] !== undefined){
330
other_pairs = other_pairs.concat(other.$object_dict[hash])
331
}
332
if(other_pairs.length == 0){
333
return false
334
}
335
for(var i = 0, len_i = pairs.length; i < len_i; i++){
336
var flag = false
337
var key = pairs[i][0],
338
value = pairs[i][1][0]
339
for(var j = 0, len_j = other_pairs.length; j < len_j; j++){
340
if($B.rich_comp("__eq__", key, other_pairs[j][0]) &&
341
$B.rich_comp("__eq__", value, other_pairs[j][1][0])){
342
flag = true
343
break
349
}
350
}
351
return true
Sep 5, 2014
352
}
353
Feb 11, 2018
354
dict.__getitem__ = function(){
355
var $ = $B.args("__getitem__", 2, {self: null, arg: null},
356
["self", "arg"], arguments, {}, null, null),
357
self = $.self,
359
return dict.$getitem(self, arg)
360
}
361
362
dict.$getitem = function(self, arg){
363
if(self.$jsobj){
364
if(self.$jsobj[arg] === undefined){
365
if(self.$jsobj.hasOwnProperty(arg)){
367
}
368
throw _b_.KeyError.$factory(arg)
369
}
370
return self.$jsobj[arg]
372
373
switch(typeof arg){
374
case "string":
375
if(self.$string_dict[arg] !== undefined){
376
return self.$string_dict[arg][0]
378
break
379
case "number":
380
if(self.$numeric_dict[arg] !== undefined){
381
return self.$numeric_dict[arg][0]
383
break
384
}
385
386
// since the key is more complex use 'default' method of getting item
387
388
var hash = _b_.hash(arg),
389
_eq = function(other){return $B.rich_comp("__eq__", arg, other)}
390
391
if(typeof arg == "object"){
392
arg.$hash = hash // cache for setdefault
393
}
394
var sk = self.$str_hash[hash]
395
if(sk !== undefined && _eq(sk)){
396
return self.$string_dict[sk][0]
398
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
399
return self.$numeric_dict[hash][0]
401
if(_b_.isinstance(arg, _b_.str)){
402
// string subclass
403
var res = self.$string_dict[arg.valueOf()]
404
if(res !== undefined){return res[0]}
407
var ix = rank(self, hash, arg)
408
if(ix > -1){
409
return self.$object_dict[hash][ix][1][0]
412
if(self.__class__ !== dict){
414
var missing_method = getattr(self.__class__, "__missing__",
415
_b_.None)
416
}catch(err){
417
console.log(err)
418
419
}
420
if(missing_method !== _b_.None){
421
return missing_method(self, arg)
424
throw _b_.KeyError.$factory(arg)
Sep 5, 2014
425
}
426
427
dict.__hash__ = _b_.None
Sep 5, 2014
428
429
function init_from_list(self, args){
430
var i = -1,
431
stop = args.length - 1,
432
si = dict.__setitem__
433
while(i++ < stop){
434
var item = args[i]
435
switch(typeof item[0]) {
436
case 'string':
437
self.$string_dict[item[0]] = [item[1], self.$order++]
438
self.$str_hash[str_hash(item[0])] = item[0]
439
self.$version++
440
break
441
case 'number':
442
self.$numeric_dict[item[0]] = [item[1], self.$order++]
443
self.$version++
444
break
445
default:
446
si(self, item[0], item[1])
447
break
448
}
449
}
450
}
451
452
dict.__init__ = function(self, first, second){
454
if(first === undefined){return $N}
455
if(second === undefined){
456
if(first.$nat != 'kw' && $B.get_class(first) === $B.JSObj){
457
for(var key in first){
458
self.$string_dict[key] = [first[key], self.$order++]
459
}
460
return _b_.None
461
}else if(first.$jsobj){
462
self.$jsobj = {}
463
for(var attr in first.$jsobj){
464
self.$jsobj[attr] = first.$jsobj[attr]
467
}else if(Array.isArray(first)){
468
init_from_list(self, first)
469
return $N
Sep 5, 2014
470
}
473
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
474
arguments, {}, "first", "second")
475
var args = $.first
476
if(args.length > 1){
477
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
478
", got 2")
479
}else if(args.length == 1){
480
args = args[0]
481
if(args.__class__ === dict){
482
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
483
forEach(function(d){
484
for(key in args[d]){self[d][key] = args[d][key]}
485
})
486
}else if(_b_.isinstance(args, dict)){
489
var keys = $B.$getattr(args, "keys", null)
490
if(keys !== null){
491
var gi = $B.$getattr(args, "__getitem__", null)
492
if(gi !== null){
493
// has keys and __getitem__ : it's a mapping, iterate on
494
// keys and values
495
gi = $B.$call(gi)
496
var kiter = _b_.iter($B.$call(keys)())
497
while(true){
498
try{
499
var key = _b_.next(kiter),
500
value = gi(key)
501
dict.__setitem__(self, key, value)
502
}catch(err){
503
if(err.__class__ === _b_.StopIteration){
504
break
505
}
506
throw err
507
}
508
}
509
return $N
510
}
511
}
512
if(! Array.isArray(args)){
513
args = _b_.list.$factory(args)
514
}
515
// Form "dict([[key1, value1], [key2,value2], ...])"
516
init_from_list(self, args)
Sep 5, 2014
517
}
519
var kw = $.second.$string_dict
520
for(var attr in kw){
521
switch(typeof attr){
522
case "string":
523
self.$string_dict[attr] = [kw[attr][0], self.$order++]
524
self.$str_hash[str_hash(attr)] = attr
525
break
526
case "number":
527
self.$numeric_dict[attr] = [kw[attr][0], self.$order++]
530
si(self, attr, kw[attr][0])
Sep 5, 2014
535
}
536
Feb 11, 2018
537
dict.__iter__ = function(self) {
538
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
539
}
540
541
dict.__ior__ = function(self, other){
542
// PEP 584
543
dict.update(self, other)
544
return self
545
}
546
Feb 11, 2018
547
dict.__len__ = function(self) {
550
if(self.$jsobj){
Mar 7, 2018
551
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
552
return _count
553
}
555
for(var k in self.$numeric_dict){_count++}
556
for(var k in self.$string_dict){_count++}
557
for(var hash in self.$object_dict){
558
_count += self.$object_dict[hash].length
559
}
Sep 5, 2014
563
Mar 7, 2018
564
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
565
Feb 11, 2018
566
dict.__new__ = function(cls){
567
if(cls === undefined){
Mar 7, 2018
568
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
570
var instance = {
572
$numeric_dict : {},
573
$object_dict : {},
576
$version: 0,
577
$order: 0
579
if(cls !== dict){
580
instance.__dict__ = $B.empty_dict()
581
}
582
return instance
585
dict.__or__ = function(self, other){
586
// PEP 584
587
if(! _b_.isinstance(other, dict)){
588
return _b_.NotImplemented
589
}
590
var res = dict.copy(self)
591
dict.update(res, other)
592
return res
593
}
594
Feb 11, 2018
595
dict.__repr__ = function(self){
596
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
597
return dict.__repr__(jsobj2dict(self.$jsobj))
599
if($B.repr.enter(self)){
600
return "{...}"
601
}
602
var res = [],
604
items.forEach(function(item){
605
try{
606
res.push(repr(item[0]) + ": " + repr(item[1]))
607
}catch(err){
608
throw err
609
}
611
$B.repr.leave(self)
Mar 7, 2018
612
return "{" + res.join(", ") + "}"
Sep 5, 2014
613
}
614
615
dict.__ror__ = function(self, other){
616
// PEP 584
617
if(! _b_.isinstance(other, dict)){
618
return _b_.NotImplemented
619
}
620
var res = dict.copy(other)
621
dict.update(res, self)
622
return res
623
}
624
625
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
626
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
627
["self", "key", "value"], arguments, {}, null, null)
628
return dict.$setitem($.self, $.key, $.value)
629
}
Nov 21, 2015
630
631
dict.$setitem = function(self, key, value, $hash){
632
// Set a dictionary item mapping key and value.
633
//
634
// If key is a string, set:
635
// - $string_dict[key] = [value, order] where "order" is an auto-increment
636
// unique id to keep track of insertion order
637
// - $str_hash[hash(key)] to key
638
//
639
// If key is a number, set $numeric_dict[key] = value
640
//
641
// If key is another object, compute its hash value:
642
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
643
// replace $string_dict[$str_hash[hash]] by value
644
// - if the hash is a key of $numeric_dict, and hash == key, replace
645
// $numeric_dict[hash] by value
646
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
647
// of [k, v] pairs. If key is equal to one of the "k", replace the
648
// matching v by value. Otherwise, add [key, value] to the list
649
// - else set $object_dict[hash] = [[key, value]]
650
//
651
// In all cases, increment attribute $version, used to detect dictionary
652
// changes during an iteration.
654
// Parameter $hash is only set if this method is called by setdefault.
655
// In this case the hash of key has already been computed and we
656
// know that the key is not present in the dictionary, so it's no
657
// use computing hash(key) again, nor testing equality of keys
659
if(self.$from_js){
660
// dictionary created by method to_dict of JSObj instances
661
value = $B.pyobj2jsobj(value)
662
}
663
if(self.$jsobj.__class__ === _b_.type){
664
self.$jsobj[key] = value
665
if(key == "__init__" || key == "__new__"){
666
// If class attribute __init__ or __new__ are reset,
667
// the factory function has to change
668
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
669
}
670
}else{
671
self.$jsobj[key] = value
676
switch(typeof key){
677
case "string":
678
if(self.$string_dict === undefined){
679
console.log("pas de string dict", self, key, value)
680
}
681
if(self.$string_dict[key] !== undefined){
682
self.$string_dict[key][0] = value
683
}else{
684
self.$string_dict[key] = [value, self.$order++]
685
self.$str_hash[str_hash(key)] = key
686
self.$version++
687
}
688
return $N
689
case "number":
690
if(self.$numeric_dict[key] !== undefined){
691
// existing key: preserve order
692
self.$numeric_dict[key][0] = value
693
}else{
694
// new key
695
self.$numeric_dict[key] = [value, self.$order++]
696
self.$version++
697
}
698
return $N
701
// if we got here the key is more complex, use default method
702
703
var hash = $hash === undefined ? _b_.hash(key) : $hash,
704
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
705
706
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
707
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
711
var sk = self.$str_hash[hash]
712
if(sk !== undefined && _eq(sk)){
713
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
718
// If $setitem is called from setdefault, don't test equality of key
719
// with any object
720
if($hash){
721
if(self.$object_dict[$hash] !== undefined){
722
self.$object_dict[$hash].push([key, [value, self.$order++]])
724
self.$object_dict[$hash] = [[key, [value, self.$order++]]]
725
}
726
self.$version++
727
return $N
728
}
729
var ix = rank(self, hash, key)
730
if(ix > -1){
731
// reset value
732
self.$object_dict[hash][ix][1] = [value,
733
self.$object_dict[hash][ix][1][1]]
734
return $N
735
}else if(self.$object_dict.hasOwnProperty(hash)){
736
self.$object_dict[hash].push([key, [value, self.$order++]])
738
self.$object_dict[hash] = [[key, [value, self.$order++]]]
Sep 5, 2014
742
}
743
744
dict.__str__ = function(){
745
return dict.__repr__.apply(null, arguments)
746
}
Sep 5, 2014
747
748
// add "reflected" methods
Feb 11, 2018
749
$B.make_rmethods(dict)
Sep 5, 2014
750
Feb 11, 2018
751
dict.clear = function(){
Sep 5, 2014
752
// Remove all items from the dictionary.
Mar 7, 2018
753
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
754
null, null),
755
self = $.self
757
self.$numeric_dict = {}
758
self.$string_dict = {}
759
self.$str_hash = {}
760
self.$object_dict = {}
762
if(self.$jsobj){
763
for(var attr in self.$jsobj){
Mar 7, 2018
764
if(attr.charAt(0) !== "$" && attr !== "__class__"){
765
delete self.$jsobj[attr]
766
}
767
}
768
}
Sep 5, 2014
772
}
773
Feb 11, 2018
774
dict.copy = function(self){
Sep 5, 2014
775
// Return a shallow copy of the dictionary
Mar 7, 2018
776
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
777
null, null),
778
self = $.self,
Sep 5, 2014
781
return res
782
}
783
Feb 11, 2018
784
dict.fromkeys = function(){
Nov 21, 2015
785
Mar 7, 2018
786
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
787
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
788
keys = $.keys,
789
value = $.value
Sep 5, 2014
791
// class method
792
var klass = $.cls,
Sep 5, 2014
796
while(1){
797
try{
798
var key = _b_.next(keys_iter)
799
if(klass === dict){dict.$setitem(res, key, value)}
800
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
801
}catch(err){
802
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
803
return res
804
}
805
throw err
806
}
807
}
808
}
809
Feb 11, 2018
810
dict.get = function(){
Mar 7, 2018
811
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
812
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
814
try{return dict.__getitem__($.self, $.key)}
815
catch(err){
816
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
817
else{throw err}
818
}
819
}
820
821
var dict_items = $B.make_view("dict_items", true)
822
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
823
Feb 11, 2018
824
dict.items = function(self){
Mar 23, 2018
825
if(arguments.length > 1){
826
var _len = arguments.length - 1,
827
_msg = "items() takes no arguments (" + _len + " given)"
828
throw _b_.TypeError.$factory(_msg)
829
}
830
var it = dict_items.$factory(to_list(self))
831
it.len_func = function(){return dict.__len__(self)}
832
return it
833
}
834
835
var dict_keys = $B.make_view("dict_keys", true)
836
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
837
Mar 23, 2018
839
if(arguments.length > 1){
840
var _len = arguments.length - 1,
841
_msg = "keys() takes no arguments (" + _len + " given)"
842
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
843
}
844
var it = dict_keys.$factory(to_list(self, 0))
845
it.len_func = function(){return dict.__len__(self)}
846
return it
Nov 21, 2015
847
}
848
Feb 11, 2018
849
dict.pop = function(){
Nov 21, 2015
850
851
var missing = {},
852
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
853
["self", "key", "_default"], arguments, {_default: missing}, null, null),
854
self = $.self,
855
key = $.key,
856
_default = $._default
Nov 21, 2015
857
Sep 5, 2014
858
try{
859
var res = dict.__getitem__(self, key)
860
dict.__delitem__(self, key)
Sep 5, 2014
861
return res
862
}catch(err){
863
if(err.__class__ === _b_.KeyError){
864
if(_default !== missing){return _default}
Sep 5, 2014
865
throw err
866
}
867
throw err
868
}
869
}
870
Feb 11, 2018
871
dict.popitem = function(self){
873
var itm = _b_.next(_b_.iter(dict.items(self)))
874
dict.__delitem__(self, itm[0])
Feb 11, 2018
875
return _b_.tuple.$factory(itm)
877
if (err.__class__ == _b_.StopIteration) {
878
throw _b_.KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
881
}
882
Feb 11, 2018
883
dict.setdefault = function(){
Nov 21, 2015
884
Mar 7, 2018
885
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
886
["self", "key", "_default"], arguments, {_default: $N}, null, null),
887
self = $.self,
888
key = $.key,
889
_default = $._default
Nov 21, 2015
890
891
try{return dict.__getitem__(self, key)}
Sep 5, 2014
892
catch(err){
893
if(err.__class__ !== _b_.KeyError){
894
throw err
895
}
896
if(_default === undefined){_default = $N}
897
var hash = key.$hash
898
key.$hash = undefined
899
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
900
return _default
901
}
902
}
903
Feb 11, 2018
904
dict.update = function(self){
Nov 21, 2015
905
Mar 7, 2018
906
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
907
{}, "args", "kw"),
908
self = $.self,
909
args = $.args,
910
kw = $.kw
911
if(args.length > 0){
912
var o = args[0]
914
if(o.$jsobj){
915
o = jsobj2dict(o.$jsobj)
916
}
918
}else if(_b_.hasattr(o, "keys")){
919
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
920
for(var i = 0, len = _keys.length; i < len; i++){
921
var _value = getattr(o, "__getitem__")(_keys[i])
922
dict.$setitem(self, _keys[i], _value)
923
}
924
}else{
925
var it = _b_.iter(o),
926
i = 0
927
while(true){
928
try{
929
var item = _b_.next(it)
930
}catch(err){
931
if(err.__class__ === _b_.StopIteration){break}
932
throw err
933
}
934
try{
935
key_value = _b_.list.$factory(item)
936
}catch(err){
937
throw _b_.TypeError.$factory("cannot convert dictionary" +
938
" update sequence element #" + i + " to a sequence")
939
}
940
if(key_value.length !== 2){
941
throw _b_.ValueError.$factory("dictionary update " +
942
"sequence element #" + i + " has length " +
943
key_value.length + "; 2 is required")
944
}
945
dict.$setitem(self, key_value[0], key_value[1])
946
i++
Sep 5, 2014
949
}
Sep 5, 2014
953
}
954
955
var dict_values = $B.make_view("dict_values")
956
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
957
Feb 11, 2018
958
dict.values = function(self){
Mar 23, 2018
959
if(arguments.length > 1){
960
var _len = arguments.length - 1,
961
_msg = "values() takes no arguments (" + _len + " given)"
962
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
963
}
964
var it = dict_values.$factory(to_list(self, 1))
965
it.len_func = function(){return dict.__len__(self)}
966
return it
Nov 21, 2015
967
}
968
969
dict.$factory = function(){
970
var res = dict.__new__(dict)
971
var args = [res]
972
for(var i = 0, len = arguments.length; i < len ; i++){
973
args.push(arguments[i])
974
}
975
dict.__init__.apply(null, args)
Sep 5, 2014
976
return res
977
}
Sep 5, 2014
979
_b_.dict = dict
Feb 11, 2018
981
$B.set_func_names(dict, "builtins")
983
$B.empty_dict = function(){
984
return {
985
__class__: dict,
986
$numeric_dict : {},
987
$object_dict : {},
988
$string_dict : {},
989
$str_hash: {},
990
$version: 0,
991
$order: 0
995
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
996
// have the attribute $infos
997
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
998
999
$B.getset_descriptor = $B.make_class("getset_descriptor",
1000
function(klass, attr){
1001
return {
1002
__class__: $B.getset_descriptor,
1003
__doc__: _b_.None,
1004
cls: klass,
1005
attr: attr
1006
}
1007
}
1008
)
1009
1010
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
1011
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
1012
}
1013
1014
$B.set_func_names($B.getset_descriptor, "builtins")
1015
1016
// Class for attribute __dict__ of classes
1017
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
1018
function(obj){
1019
if(_b_.isinstance(obj, dict)){
1020
// obj is a dictionary, with $string_dict table such that
1021
// obj.$string_dict[key] = [value, rank]
1022
// Transform it into an object with attribute $jsobj such that
1023
// res.$jsobj[key] = value
1024
var res = $B.obj_dict(dict.$to_obj(obj))
1025
}else{
1026
var res = $B.obj_dict(obj)
1027
}
Feb 12, 2018
1028
res.__class__ = mappingproxy
1029
return res
1030
}
1031
)
Feb 12, 2018
1033
mappingproxy.__setitem__ = function(){
Mar 7, 2018
1034
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
1035
"item assignment")
1038
for(var attr in dict){
1039
if(mappingproxy[attr] !== undefined ||
1040
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
1041
"clear", "fromkeys", "pop", "popitem", "setdefault",
1042
"update"].indexOf(attr) > -1){
1043
continue
1044
}
1045
if(typeof dict[attr] == "function"){
1046
mappingproxy[attr] = (function(key){
1047
return function(){
1048
return dict[key].apply(null, arguments)
1049
}
1050
})(attr)
1051
}else{
1052
mappingproxy[attr] = dict[attr]
1053
}
1054
}
1055
Feb 12, 2018
1056
$B.set_func_names(mappingproxy, "builtins")
Mar 7, 2018
1061
if(attr.charAt(0) != "$" && attr !== "__class__"){
1062
if(x[attr] === null){
1063
d.$string_dict[attr] = [_b_.None, d.$order++]
1064
}else if(x[attr] === undefined){
1065
continue
1066
}else if(x[attr].$jsobj === x){
1067
d.$string_dict[attr] = [d, d.$order++]
1069
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$order++]
1071
}
1072
}
1073
return d
1074
}
1076
$B.obj_dict = function(obj, from_js){
1077
var klass = obj.__class__ || $B.get_class(obj)
1078
if(klass !== undefined && klass.$native){
1079
throw _b_.AttributeError.$factory(klass.__name__ +
1080
" has no attribute '__dict__'")}
1082
res.$jsobj = obj
1083
res.$from_js = from_js // set to true if
1084
return res
1085
}
1086
Sep 5, 2014
1087
})(__BRYTHON__)