Skip to content
Permalink
Newer
Older
100644 1085 lines (969 sloc) 31.7 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.__class__ === $B.JSObject){
457
self.$jsobj = first.js
458
return $N
459
}else if(first.$jsobj){
460
self.$jsobj = {}
461
for(var attr in first.$jsobj){
462
self.$jsobj[attr] = first.$jsobj[attr]
465
}else if(Array.isArray(first)){
466
init_from_list(self, first)
467
return $N
Sep 5, 2014
468
}
471
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
472
arguments, {}, "first", "second")
473
var args = $.first
474
if(args.length > 1){
475
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
476
", got 2")
477
}else if(args.length == 1){
478
args = args[0]
479
if(args.__class__ === dict){
480
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
481
forEach(function(d){
482
for(key in args[d]){self[d][key] = args[d][key]}
483
})
484
}else if(_b_.isinstance(args, dict)){
487
var keys = $B.$getattr(args, "keys", null)
488
if(keys !== null){
489
var gi = $B.$getattr(args, "__getitem__", null)
490
if(gi !== null){
491
// has keys and __getitem__ : it's a mapping, iterate on
492
// keys and values
493
gi = $B.$call(gi)
494
var kiter = _b_.iter($B.$call(keys)())
495
while(true){
496
try{
497
var key = _b_.next(kiter),
498
value = gi(key)
499
dict.__setitem__(self, key, value)
500
}catch(err){
501
if(err.__class__ === _b_.StopIteration){
502
break
503
}
504
throw err
505
}
506
}
507
return $N
508
}
509
}
510
if(! Array.isArray(args)){
511
args = _b_.list.$factory(args)
512
}
513
// Form "dict([[key1, value1], [key2,value2], ...])"
514
init_from_list(self, args)
Sep 5, 2014
515
}
517
var kw = $.second.$string_dict
518
for(var attr in kw){
519
switch(typeof attr){
520
case "string":
521
self.$string_dict[attr] = [kw[attr][0], self.$order++]
522
self.$str_hash[str_hash(attr)] = attr
523
break
524
case "number":
525
self.$numeric_dict[attr] = [kw[attr][0], self.$order++]
528
si(self, attr, kw[attr][0])
Sep 5, 2014
533
}
534
Feb 11, 2018
535
dict.__iter__ = function(self) {
536
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
537
}
538
539
dict.__ior__ = function(self, other){
540
// PEP 584
541
dict.update(self, other)
542
return self
543
}
544
Feb 11, 2018
545
dict.__len__ = function(self) {
548
if(self.$jsobj){
Mar 7, 2018
549
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
550
return _count
551
}
553
for(var k in self.$numeric_dict){_count++}
554
for(var k in self.$string_dict){_count++}
555
for(var hash in self.$object_dict){
556
_count += self.$object_dict[hash].length
557
}
Sep 5, 2014
561
Mar 7, 2018
562
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
563
Feb 11, 2018
564
dict.__new__ = function(cls){
565
if(cls === undefined){
Mar 7, 2018
566
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
568
var instance = {
570
$numeric_dict : {},
571
$object_dict : {},
574
$version: 0,
575
$order: 0
577
if(cls !== dict){
578
instance.__dict__ = $B.empty_dict()
579
}
580
return instance
583
dict.__or__ = function(self, other){
584
// PEP 584
585
if(! _b_.isinstance(other, dict)){
586
return _b_.NotImplemented
587
}
588
var res = dict.copy(self)
589
dict.update(res, other)
590
return res
591
}
592
Feb 11, 2018
593
dict.__repr__ = function(self){
594
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
595
return dict.__repr__(jsobj2dict(self.$jsobj))
597
if($B.repr.enter(self)){
598
return "{...}"
599
}
600
var res = [],
602
items.forEach(function(item){
603
try{
604
res.push(repr(item[0]) + ": " + repr(item[1]))
605
}catch(err){
606
throw err
607
}
609
$B.repr.leave(self)
Mar 7, 2018
610
return "{" + res.join(", ") + "}"
Sep 5, 2014
611
}
612
613
dict.__ror__ = function(self, other){
614
// PEP 584
615
if(! _b_.isinstance(other, dict)){
616
return _b_.NotImplemented
617
}
618
var res = dict.copy(other)
619
dict.update(res, self)
620
return res
621
}
622
623
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
624
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
625
["self", "key", "value"], arguments, {}, null, null)
626
return dict.$setitem($.self, $.key, $.value)
627
}
Nov 21, 2015
628
629
dict.$setitem = function(self, key, value, $hash){
630
// Set a dictionary item mapping key and value.
631
//
632
// If key is a string, set:
633
// - $string_dict[key] = [value, order] where "order" is an auto-increment
634
// unique id to keep track of insertion order
635
// - $str_hash[hash(key)] to key
636
//
637
// If key is a number, set $numeric_dict[key] = value
638
//
639
// If key is another object, compute its hash value:
640
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
641
// replace $string_dict[$str_hash[hash]] by value
642
// - if the hash is a key of $numeric_dict, and hash == key, replace
643
// $numeric_dict[hash] by value
644
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
645
// of [k, v] pairs. If key is equal to one of the "k", replace the
646
// matching v by value. Otherwise, add [key, value] to the list
647
// - else set $object_dict[hash] = [[key, value]]
648
//
649
// In all cases, increment attribute $version, used to detect dictionary
650
// changes during an iteration.
652
// Parameter $hash is only set if this method is called by setdefault.
653
// In this case the hash of key has already been computed and we
654
// know that the key is not present in the dictionary, so it's no
655
// use computing hash(key) again, nor testing equality of keys
657
if(self.$from_js){
658
// dictionary created by method to_dict of JSObject instances
659
value = $B.pyobj2jsobj(value)
660
}
661
if(self.$jsobj.__class__ === _b_.type){
662
self.$jsobj[key] = value
663
if(key == "__init__" || key == "__new__"){
664
// If class attribute __init__ or __new__ are reset,
665
// the factory function has to change
666
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
667
}
668
}else{
669
self.$jsobj[key] = value
674
switch(typeof key){
675
case "string":
676
if(self.$string_dict === undefined){
677
console.log("pas de string dict", self, key, value)
678
}
679
if(self.$string_dict[key] !== undefined){
680
self.$string_dict[key][0] = value
681
}else{
682
self.$string_dict[key] = [value, self.$order++]
683
self.$str_hash[str_hash(key)] = key
684
self.$version++
685
}
686
return $N
687
case "number":
688
if(self.$numeric_dict[key] !== undefined){
689
// existing key: preserve order
690
self.$numeric_dict[key][0] = value
691
}else{
692
// new key
693
self.$numeric_dict[key] = [value, self.$order++]
694
self.$version++
695
}
696
return $N
699
// if we got here the key is more complex, use default method
700
701
var hash = $hash === undefined ? _b_.hash(key) : $hash,
702
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
703
704
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
705
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
709
var sk = self.$str_hash[hash]
710
if(sk !== undefined && _eq(sk)){
711
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
716
// If $setitem is called from setdefault, don't test equality of key
717
// with any object
718
if($hash){
719
if(self.$object_dict[$hash] !== undefined){
720
self.$object_dict[$hash].push([key, [value, self.$order++]])
722
self.$object_dict[$hash] = [[key, [value, self.$order++]]]
723
}
724
self.$version++
725
return $N
726
}
727
var ix = rank(self, hash, key)
728
if(ix > -1){
729
// reset value
730
self.$object_dict[hash][ix][1] = [value,
731
self.$object_dict[hash][ix][1][1]]
732
return $N
733
}else if(self.$object_dict.hasOwnProperty(hash)){
734
self.$object_dict[hash].push([key, [value, self.$order++]])
736
self.$object_dict[hash] = [[key, [value, self.$order++]]]
Sep 5, 2014
740
}
741
742
dict.__str__ = function(){
743
return dict.__repr__.apply(null, arguments)
744
}
Sep 5, 2014
745
746
// add "reflected" methods
Feb 11, 2018
747
$B.make_rmethods(dict)
Sep 5, 2014
748
Feb 11, 2018
749
dict.clear = function(){
Sep 5, 2014
750
// Remove all items from the dictionary.
Mar 7, 2018
751
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
752
null, null),
753
self = $.self
755
self.$numeric_dict = {}
756
self.$string_dict = {}
757
self.$str_hash = {}
758
self.$object_dict = {}
760
if(self.$jsobj){
761
for(var attr in self.$jsobj){
Mar 7, 2018
762
if(attr.charAt(0) !== "$" && attr !== "__class__"){
763
delete self.$jsobj[attr]
764
}
765
}
766
}
Sep 5, 2014
770
}
771
Feb 11, 2018
772
dict.copy = function(self){
Sep 5, 2014
773
// Return a shallow copy of the dictionary
Mar 7, 2018
774
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
775
null, null),
776
self = $.self,
Sep 5, 2014
779
return res
780
}
781
Feb 11, 2018
782
dict.fromkeys = function(){
Nov 21, 2015
783
Mar 7, 2018
784
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
785
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
786
keys = $.keys,
787
value = $.value
Sep 5, 2014
789
// class method
790
var klass = $.cls,
Sep 5, 2014
794
while(1){
795
try{
796
var key = _b_.next(keys_iter)
797
if(klass === dict){dict.$setitem(res, key, value)}
798
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
799
}catch(err){
800
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
801
return res
802
}
803
throw err
804
}
805
}
806
}
807
Feb 11, 2018
808
dict.get = function(){
Mar 7, 2018
809
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
810
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
812
try{return dict.__getitem__($.self, $.key)}
813
catch(err){
814
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
815
else{throw err}
816
}
817
}
818
819
var dict_items = $B.make_view("dict_items", true)
820
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
821
Feb 11, 2018
822
dict.items = function(self){
Mar 23, 2018
823
if(arguments.length > 1){
824
var _len = arguments.length - 1,
825
_msg = "items() takes no arguments (" + _len + " given)"
826
throw _b_.TypeError.$factory(_msg)
827
}
828
var it = dict_items.$factory(to_list(self))
829
it.len_func = function(){return dict.__len__(self)}
830
return it
831
}
832
833
var dict_keys = $B.make_view("dict_keys", true)
834
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
835
Mar 23, 2018
837
if(arguments.length > 1){
838
var _len = arguments.length - 1,
839
_msg = "keys() takes no arguments (" + _len + " given)"
840
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
841
}
842
var it = dict_keys.$factory(to_list(self, 0))
843
it.len_func = function(){return dict.__len__(self)}
844
return it
Nov 21, 2015
845
}
846
Feb 11, 2018
847
dict.pop = function(){
Nov 21, 2015
848
849
var missing = {},
850
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
851
["self", "key", "_default"], arguments, {_default: missing}, null, null),
852
self = $.self,
853
key = $.key,
854
_default = $._default
Nov 21, 2015
855
Sep 5, 2014
856
try{
857
var res = dict.__getitem__(self, key)
858
dict.__delitem__(self, key)
Sep 5, 2014
859
return res
860
}catch(err){
861
if(err.__class__ === _b_.KeyError){
862
if(_default !== missing){return _default}
Sep 5, 2014
863
throw err
864
}
865
throw err
866
}
867
}
868
Feb 11, 2018
869
dict.popitem = function(self){
871
var itm = _b_.next(_b_.iter(dict.items(self)))
872
dict.__delitem__(self, itm[0])
Feb 11, 2018
873
return _b_.tuple.$factory(itm)
875
if (err.__class__ == _b_.StopIteration) {
876
throw _b_.KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
879
}
880
Feb 11, 2018
881
dict.setdefault = function(){
Nov 21, 2015
882
Mar 7, 2018
883
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
884
["self", "key", "_default"], arguments, {_default: $N}, null, null),
885
self = $.self,
886
key = $.key,
887
_default = $._default
Nov 21, 2015
888
889
try{return dict.__getitem__(self, key)}
Sep 5, 2014
890
catch(err){
891
if(err.__class__ !== _b_.KeyError){
892
throw err
893
}
894
if(_default === undefined){_default = $N}
895
var hash = key.$hash
896
key.$hash = undefined
897
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
898
return _default
899
}
900
}
901
Feb 11, 2018
902
dict.update = function(self){
Nov 21, 2015
903
Mar 7, 2018
904
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
905
{}, "args", "kw"),
906
self = $.self,
907
args = $.args,
908
kw = $.kw
909
if(args.length > 0){
910
var o = args[0]
912
if(o.$jsobj){
913
o = jsobj2dict(o.$jsobj)
914
}
916
}else if(_b_.hasattr(o, "keys")){
917
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
918
for(var i = 0, len = _keys.length; i < len; i++){
919
var _value = getattr(o, "__getitem__")(_keys[i])
920
dict.$setitem(self, _keys[i], _value)
921
}
922
}else{
923
var it = _b_.iter(o),
924
i = 0
925
while(true){
926
try{
927
var item = _b_.next(it)
928
}catch(err){
929
if(err.__class__ === _b_.StopIteration){break}
930
throw err
931
}
932
try{
933
key_value = _b_.list.$factory(item)
934
}catch(err){
935
throw _b_.TypeError.$factory("cannot convert dictionary" +
936
" update sequence element #" + i + " to a sequence")
937
}
938
if(key_value.length !== 2){
939
throw _b_.ValueError.$factory("dictionary update " +
940
"sequence element #" + i + " has length " +
941
key_value.length + "; 2 is required")
942
}
943
dict.$setitem(self, key_value[0], key_value[1])
944
i++
Sep 5, 2014
947
}
Sep 5, 2014
951
}
952
953
var dict_values = $B.make_view("dict_values")
954
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
955
Feb 11, 2018
956
dict.values = function(self){
Mar 23, 2018
957
if(arguments.length > 1){
958
var _len = arguments.length - 1,
959
_msg = "values() takes no arguments (" + _len + " given)"
960
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
961
}
962
var it = dict_values.$factory(to_list(self, 1))
963
it.len_func = function(){return dict.__len__(self)}
964
return it
Nov 21, 2015
965
}
966
967
dict.$factory = function(){
968
var res = dict.__new__(dict)
969
var args = [res]
970
for(var i = 0, len = arguments.length; i < len ; i++){
971
args.push(arguments[i])
972
}
973
dict.__init__.apply(null, args)
Sep 5, 2014
974
return res
975
}
Sep 5, 2014
977
_b_.dict = dict
Feb 11, 2018
979
$B.set_func_names(dict, "builtins")
981
$B.empty_dict = function(){
982
return {
983
__class__: dict,
984
$numeric_dict : {},
985
$object_dict : {},
986
$string_dict : {},
987
$str_hash: {},
988
$version: 0,
989
$order: 0
993
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
994
// have the attribute $infos
995
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
996
997
$B.getset_descriptor = $B.make_class("getset_descriptor",
998
function(klass, attr){
999
return {
1000
__class__: $B.getset_descriptor,
1001
__doc__: _b_.None,
1002
cls: klass,
1003
attr: attr
1004
}
1005
}
1006
)
1007
1008
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
1009
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
1010
}
1011
1012
$B.set_func_names($B.getset_descriptor, "builtins")
1013
1014
// Class for attribute __dict__ of classes
1015
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
1016
function(obj){
1017
if(_b_.isinstance(obj, dict)){
1018
// obj is a dictionary, with $string_dict table such that
1019
// obj.$string_dict[key] = [value, rank]
1020
// Transform it into an object with attribute $jsobj such that
1021
// res.$jsobj[key] = value
1022
var res = $B.obj_dict(dict.$to_obj(obj))
1023
}else{
1024
var res = $B.obj_dict(obj)
1025
}
Feb 12, 2018
1026
res.__class__ = mappingproxy
1027
return res
1028
}
1029
)
Feb 12, 2018
1031
mappingproxy.__setitem__ = function(){
Mar 7, 2018
1032
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
1033
"item assignment")
1036
for(var attr in dict){
1037
if(mappingproxy[attr] !== undefined ||
1038
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
1039
"clear", "fromkeys", "pop", "popitem", "setdefault",
1040
"update"].indexOf(attr) > -1){
1041
continue
1042
}
1043
if(typeof dict[attr] == "function"){
1044
mappingproxy[attr] = (function(key){
1045
return function(){
1046
return dict[key].apply(null, arguments)
1047
}
1048
})(attr)
1049
}else{
1050
mappingproxy[attr] = dict[attr]
1051
}
1052
}
1053
Feb 12, 2018
1054
$B.set_func_names(mappingproxy, "builtins")
Mar 7, 2018
1059
if(attr.charAt(0) != "$" && attr !== "__class__"){
1060
if(x[attr] === null){
1061
d.$string_dict[attr] = [_b_.None, d.$order++]
1062
}else if(x[attr] === undefined){
1063
continue
1064
}else if(x[attr].$jsobj === x){
1065
d.$string_dict[attr] = [d, d.$order++]
1067
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$order++]
1069
}
1070
}
1071
return d
1072
}
1074
$B.obj_dict = function(obj, from_js){
1075
var klass = obj.__class__ || $B.get_class(obj)
1076
if(klass !== undefined && klass.$native){
1077
throw _b_.AttributeError.$factory(klass.__name__ +
1078
" has no attribute '__dict__'")}
1080
res.$jsobj = obj
1081
res.$from_js = from_js // set to true if
1082
return res
1083
}
1084
Sep 5, 2014
1085
})(__BRYTHON__)