Skip to content
Permalink
Newer
Older
100644 1036 lines (924 sloc) 30.5 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)
str
Feb 10, 2018
32
str_hash = _b_.str.__hash__,
Sep 5, 2014
34
35
var set_ops = ["eq", "add", "sub", "and", "or", "xor", "le", "lt", "ge", "gt"]
36
37
$B.make_view = function(name, set_like){
38
var klass = $B.make_class(name, function(items){
39
return {
40
__class__: klass,
41
__dict__: _b_.dict.$factory(),
42
counter: -1,
43
items: items,
44
len: items.length
45
}
46
})
47
48
if(set_like){
49
for(var i = 0, len = set_ops.length; i < len; i++){
50
var op = "__" + set_ops[i] + "__"
51
klass[op] = (function(op){
52
return function(self, other){
53
// compare set of items to other
54
return _b_.set[op](_b_.set.$factory(self),
55
_b_.set.$factory(other))
56
}
57
})(op)
58
}
59
}
60
klass.__iter__ = function(self){
61
var it = klass.$iterator.$factory(self.items)
62
it.len_func = self.len_func
63
return it
64
}
65
66
klass.__len__ = function(self){
67
return self.len
68
}
70
klass.__repr__ = function(self){
71
return klass.$infos.__name__ + '(' + _b_.repr(self.items) + ')'
72
}
73
74
$B.set_func_names(klass, "builtins")
75
return klass
76
}
77
78
// Special version of __next__ for iterators on dict keys / values / items.
79
// Checks that the dictionary size didn't change during iteration.
80
function dict_iterator_next(self){
81
if(self.len_func() != self.len){
82
throw RuntimeError.$factory("dictionary changed size during iteration")
83
}
84
self.counter++
85
if(self.counter < self.items.length){
86
return self.items[self.counter]
87
}
88
throw _b_.StopIteration.$factory("StopIteration")
89
}
90
Feb 11, 2018
91
var dict = {
Feb 11, 2018
92
__class__: _b_.type,
93
__mro__: [object],
94
$infos: {
95
__module__: "builtins",
96
__name__: "dict"
97
},
Feb 11, 2018
98
$is_class: true,
99
$native: true
Sep 5, 2014
100
}
101
102
dict.$to_obj = function(d){
103
// Function applied to dictionary that only have string keys,
104
// return a Javascript objects with the kays mapped to the value,
105
// excluding the insertion rank
106
var res = {}
107
for(var key in d.$string_dict){
108
res[key] = d.$string_dict[key][0]
109
}
110
return res
111
}
112
113
function to_list(d, ix){
114
var items = [],
115
item
117
if(d.$jsobj){
Mar 7, 2018
120
if(attr.charAt(0) != "$"){
121
var val = d.$jsobj[attr]
122
if(val === undefined){val = _b_.NotImplemented}
123
else if(val === null){val = $N}
127
}else{
128
for(var k in d.$numeric_dict){
129
items.push([parseFloat(k), d.$numeric_dict[k]])
130
}
132
for(var k in d.$string_dict){items.push([k, d.$string_dict[k]])}
134
for(var k in d.$object_dict){
135
d.$object_dict[k].forEach(function(item){
136
items.push(item)
137
})
138
}
139
// sort by insertion order
140
items.sort(function(a, b){
141
return a[1][1] - b[1][1]
142
})
143
items = items.map(function(item){return [item[0], item[1][0]]})
146
if(ix !== undefined){
147
return items.map(function(item){return item[ix]})
148
}else{
149
items.__class__ = _b_.tuple
150
return items.map(function(item){
151
item.__class__ = _b_.tuple; return item}
152
)
153
}
Feb 9, 2015
155
156
$B.dict_to_list = to_list // used in py_types.js
157
158
// Special version of __next__ for iterators on dict keys / values / items.
159
// Checks that the dictionary size didn't change during iteration.
160
function dict_iterator_next(self){
161
if(self.len_func() != self.len){
162
throw RuntimeError.$factory("dictionary changed size during iteration")
163
}
164
self.counter++
165
if(self.counter < self.items.length){
166
return self.items[self.counter]
168
throw _b_.StopIteration.$factory("StopIteration")
172
var $copy_dict = function(left, right){
174
si = dict.$setitem
175
right.$version = right.$version || 0
176
var right_version = right.$version || 0
177
for(var i = 0, len = _l.length; i < len; i++){
178
si(left, _l[i][0], _l[i][1])
179
if(right.$version != right_version){
180
throw _b_.RuntimeError.$factory("dict mutated during update")
181
}
182
}
185
function rank(self, hash, key){
186
// Search if object key, with hash = hash(key), is in
187
// self.$object_dict
188
var pairs = self.$object_dict[hash]
189
if(pairs !== undefined){
190
for(var i = 0, len = pairs.length; i < len; i++){
191
if($B.rich_comp("__eq__", key, pairs[i][0])){
192
return i
193
}
194
}
195
}
196
return -1
197
}
198
Feb 11, 2018
199
dict.__bool__ = function () {
Mar 7, 2018
200
var $ = $B.args("__bool__", 1, {self: null}, ["self"],
201
arguments, {}, null, null)
Feb 11, 2018
202
return dict.__len__($.self) > 0
Feb 11, 2018
205
dict.__contains__ = function(){
Nov 21, 2015
206
207
var $ = $B.args("__contains__", 2, {self: null, key: null},
208
["self", "key"], arguments, {}, null, null),
209
self = $.self,
211
if(self.$is_namespace){key = $B.to_alias(key)} // issue 1244
212
213
if(self.$jsobj){
214
return self.$jsobj[key] !== undefined
215
}
217
switch(typeof key) {
219
return self.$string_dict[key] !== undefined
221
return self.$numeric_dict[key] !== undefined
222
}
223
224
var hash = _b_.hash(key)
225
if(self.$str_hash[hash] !== undefined &&
226
$B.rich_comp("__eq__", key, self.$str_hash[hash])){return true}
227
if(self.$numeric_dict[hash] !== undefined &&
228
$B.rich_comp("__eq__", key, hash)){return true}
229
return rank(self, hash, key) > -1
Sep 5, 2014
230
}
231
Feb 11, 2018
232
dict.__delitem__ = function(){
Nov 21, 2015
233
234
var $ = $B.args("__eq__", 2, {self: null, arg: null},
235
["self", "arg"], arguments, {}, null, null),
236
self = $.self,
Nov 21, 2015
238
239
if(self.$jsobj){
240
if(self.$jsobj[arg] === undefined){throw KeyError.$factory(arg)}
241
delete self.$jsobj[arg]
244
switch(typeof arg){
245
case "string":
246
if(self.$string_dict[arg] === undefined){
247
throw KeyError.$factory(_b_.str.$factory(arg))
248
}
249
delete self.$string_dict[arg]
250
delete self.$str_hash[str_hash(arg)]
252
return $N
253
case "number":
254
if(self.$numeric_dict[arg] === undefined){
255
throw KeyError.$factory(_b_.str.$factory(arg))
257
delete self.$numeric_dict[arg]
261
// go with defaults
262
263
var hash = _b_.hash(arg),
264
ix
266
if((ix = rank(self, hash, arg)) > -1){
267
self.$object_dict[hash].splice(ix, 1)
268
}else{
269
throw KeyError.$factory(_b_.str.$factory(arg))
Sep 5, 2014
274
}
275
Feb 11, 2018
276
dict.__eq__ = function(){
Mar 7, 2018
277
var $ = $B.args("__eq__", 2, {self: null, other: null},
278
["self", "other"], arguments, {}, null, null),
279
self = $.self,
280
other = $.other
Mar 7, 2018
282
if(! isinstance(other, dict)){return false}
284
if(self.$jsobj){self = jsobj2dict(self.$jsobj)}
285
if(other.$jsobj){other = jsobj2dict(other.$jsobj)}
286
if(dict.__len__(self) != dict.__len__(other)){
287
return false
288
}
290
if(self.$string_dict.length != other.$string_dict.length){
294
for(var k in self.$numeric_dict){
295
if(other.$numeric_dict.hasOwnProperty(k)){
296
if(!$B.rich_comp("__eq__", other.$numeric_dict[k][0],
297
self.$numeric_dict[k][0])){
298
return false
299
}
300
}else if(other.$object_dict.hasOwnProperty(k)){
301
var pairs = other.$object_dict[k],
302
flag = false
303
for(var i = 0, len = pairs.length; i < len; i++){
304
if($B.rich_comp("__eq__", k, pairs[i][0]) &&
305
$B.rich_comp("__eq__", self.$numeric_dict[k],
306
pairs[i][1])){
307
flag = true
308
break
309
}
311
if(! flag){return false}
Nov 21, 2015
314
}
315
}
316
for(var k in self.$string_dict){
317
if(!other.$string_dict.hasOwnProperty(k) ||
318
!$B.rich_comp("__eq__", other.$string_dict[k][0],
319
self.$string_dict[k][0])){
Nov 21, 2015
321
}
322
}
323
for(var hash in self.$object_dict){
324
var pairs = self.$object_dict[hash]
325
// Get all (key, value) pairs in other that have the same hash
326
var other_pairs = []
327
if(other.$numeric_dict[hash] !== undefined){
328
other_pairs.push([hash, other.$numeric_dict[hash]])
329
}
330
if(other.$object_dict[hash] !== undefined){
331
other_pairs = other_pairs.concat(other.$object_dict[hash])
332
}
333
if(other_pairs.length == 0){
334
return false
335
}
336
for(var i = 0, len_i = pairs.length; i < len_i; i++){
337
var flag = false
338
var key = pairs[i][0],
339
value = pairs[i][1][0]
340
for(var j = 0, len_j = other_pairs.length; j < len_j; j++){
341
if($B.rich_comp("__eq__", key, other_pairs[j][0]) &&
342
$B.rich_comp("__eq__", value, other_pairs[j][1][0])){
343
flag = true
344
break
350
}
351
}
352
return true
Sep 5, 2014
353
}
354
Feb 11, 2018
355
dict.__getitem__ = function(){
356
var $ = $B.args("__getitem__", 2, {self: null, arg: null},
357
["self", "arg"], arguments, {}, null, null),
358
self = $.self,
360
return dict.$getitem(self, arg)
361
}
362
363
dict.$getitem = function(self, arg){
364
if(self.$jsobj){
365
if(self.$jsobj[arg] === undefined){
366
if(self.$jsobj.hasOwnProperty(arg)){
368
}
369
throw _b_.KeyError.$factory(arg)
370
}
371
return self.$jsobj[arg]
373
374
switch(typeof arg){
375
case "string":
376
if(self.$string_dict[arg] !== undefined){
377
return self.$string_dict[arg][0]
379
break
380
case "number":
381
if(self.$numeric_dict[arg] !== undefined){
382
return self.$numeric_dict[arg][0]
384
break
385
}
386
387
// since the key is more complex use 'default' method of getting item
388
389
var hash = _b_.hash(arg),
390
_eq = function(other){return $B.rich_comp("__eq__", arg, other)}
391
392
if(typeof arg == "object"){
393
arg.$hash = hash // cache for setdefault
394
}
395
var sk = self.$str_hash[hash]
396
if(sk !== undefined && _eq(sk)){
397
return self.$string_dict[sk][0]
399
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
400
return self.$numeric_dict[hash][0]
401
}
402
if(isinstance(arg, _b_.str)){
403
// string subclass
404
var res = self.$string_dict[arg.valueOf()]
405
if(res !== undefined){return res[0]}
408
var ix = rank(self, hash, arg)
409
if(ix > -1){
410
return self.$object_dict[hash][ix][1][0]
413
if(self.__class__ !== dict){
415
var missing_method = getattr(self.__class__, "__missing__",
416
_b_.None)
417
}catch(err){
418
console.log(err)
419
420
}
421
if(missing_method !== _b_.None){
422
return missing_method(self, arg)
Sep 5, 2014
426
}
427
428
dict.__hash__ = _b_.None
Sep 5, 2014
429
430
function init_from_list(self, args){
431
var i = -1,
432
stop = args.length - 1,
433
si = dict.__setitem__
434
while(i++ < stop){
435
var item = args[i]
436
switch(typeof item[0]) {
437
case 'string':
438
self.$string_dict[item[0]] = [item[1], self.$version]
439
self.$str_hash[str_hash(item[0])] = item[0]
440
self.$version++
441
break
442
case 'number':
443
self.$numeric_dict[item[0]] = [item[1], self.$version]
444
self.$version++
445
break
446
default:
447
si(self, item[0], item[1])
448
break
449
}
450
}
451
}
452
453
dict.__init__ = function(self, first, second){
455
if(first === undefined){return $N}
456
if(second === undefined){
457
if(first.__class__ === $B.JSObject){
458
self.$jsobj = first.js
459
return $N
460
}else if(first.$jsobj){
461
self.$jsobj = {}
462
for(var attr in first.$jsobj){
463
self.$jsobj[attr] = first.$jsobj[attr]
466
}else if(Array.isArray(first)){
467
init_from_list(self, first)
468
return $N
Sep 5, 2014
469
}
472
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
473
arguments, {}, "first", "second")
474
var args = $.first
475
if(args.length > 1){
476
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
477
", got 2")
478
}else if(args.length == 1){
479
args = args[0]
480
if(args.__class__ === dict){
481
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
482
forEach(function(d){
483
for(key in args[d]){self[d][key] = args[d][key]}
484
})
485
}else if(isinstance(args, dict)){
486
$copy_dict(self, args)
488
var keys = $B.$getattr(args, "keys", null)
489
if(keys !== null){
490
var gi = $B.$getattr(args, "__getitem__", null)
491
if(gi !== null){
492
// has keys and __getitem__ : it's a mapping, iterate on
493
// keys and values
494
gi = $B.$call(gi)
495
var kiter = _b_.iter($B.$call(keys)())
496
while(true){
497
try{
498
var key = _b_.next(kiter),
499
value = gi(key)
500
dict.__setitem__(self, key, value)
501
}catch(err){
502
if(err.__class__ === _b_.StopIteration){
503
break
504
}
505
throw err
506
}
507
}
508
return $N
509
}
510
}
511
if(! Array.isArray(args)){
512
args = _b_.list.$factory(args)
513
}
514
// Form "dict([[key1, value1], [key2,value2], ...])"
515
init_from_list(self, args)
Sep 5, 2014
516
}
518
var kw = $.second.$string_dict
519
for(var attr in kw){
520
switch(typeof attr){
521
case "string":
522
self.$string_dict[attr] = kw[attr]
523
self.$str_hash[str_hash(attr)] = attr
524
break
525
case "number":
526
self.$numeric_dict[attr] = kw[attr]
527
break
528
default:
529
si(self, attr, kw[attr])
530
break
531
}
Sep 5, 2014
534
}
535
Feb 11, 2018
536
dict.__iter__ = function(self) {
537
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
538
}
539
Feb 11, 2018
540
dict.__len__ = function(self) {
543
if(self.$jsobj){
Mar 7, 2018
544
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
545
return _count
546
}
548
for(var k in self.$numeric_dict){_count++}
549
for(var k in self.$string_dict){_count++}
550
for(var hash in self.$object_dict){
551
_count += self.$object_dict[hash].length
552
}
Sep 5, 2014
556
Mar 7, 2018
557
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
558
Feb 11, 2018
559
dict.__new__ = function(cls){
560
if(cls === undefined){
Mar 7, 2018
561
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
563
var instance = {
565
$numeric_dict : {},
566
$object_dict : {},
568
$str_hash: {},
569
$version: 0
571
if(cls !== dict){
572
instance.__dict__ = _b_.dict.$factory()
573
}
574
return instance
Feb 11, 2018
577
dict.__repr__ = function(self){
578
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
579
return dict.__repr__(jsobj2dict(self.$jsobj))
581
if($B.repr.enter(self)){
582
return "{...}"
583
}
584
var res = [],
586
items.forEach(function(item){
587
try{
588
res.push(repr(item[0]) + ": " + repr(item[1]))
589
}catch(err){
590
throw err
591
}
593
$B.repr.leave(self)
Mar 7, 2018
594
return "{" + res.join(", ") + "}"
Sep 5, 2014
595
}
596
597
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
598
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
599
["self", "key", "value"], arguments, {}, null, null)
600
return dict.$setitem($.self, $.key, $.value)
601
}
Nov 21, 2015
602
603
dict.$setitem = function(self, key, value, $hash){
604
// Set a dictionary item mapping key and value.
605
//
606
// If key is a string, set:
607
// - $string_dict[key] = [value, order] where "order" is an auto-increment
608
// unique id to keep track of insertion order
609
// - $str_hash[hash(key)] to key
610
//
611
// If key is a number, set $numeric_dict[key] = value
612
//
613
// If key is another object, compute its hash value:
614
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
615
// replace $string_dict[$str_hash[hash]] by value
616
// - if the hash is a key of $numeric_dict, and hash == key, replace
617
// $numeric_dict[hash] by value
618
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
619
// of [k, v] pairs. If key is equal to one of the "k", replace the
620
// matching v by value. Otherwise, add [key, value] to the list
621
// - else set $object_dict[hash] = [[key, value]]
622
//
623
// In all cases, increment attribute $version, used to detect dictionary
624
// changes during an iteration.
626
// Parameter $hash is only set if this method is called by setdefault.
627
// In this case the hash of key has already been computed and we
628
// know that the key is not present in the dictionary, so it's no
629
// use computing hash(key) again, nor testing equality of keys
631
if(self.$from_js){
632
// dictionary created by method to_dict of JSObject instances
633
value = $B.pyobj2jsobj(value)
634
}
635
if(self.$jsobj.__class__ === _b_.type){
636
self.$jsobj[key] = value
637
if(key == "__init__" || key == "__new__"){
638
// If class attribute __init__ or __new__ are reset,
639
// the factory function has to change
640
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
641
}
642
}else{
643
self.$jsobj[key] = value
648
switch(typeof key){
649
case "string":
650
if(self.$string_dict === undefined){
651
console.log("pas de string dict", self, key, value)
652
}
653
self.$string_dict[key] = [value, self.$version]
654
self.$str_hash[str_hash(key)] = key
656
return $N
657
case "number":
658
self.$numeric_dict[key] = [value, self.$version]
660
return $N
663
// if we got here the key is more complex, use default method
664
665
var hash = $hash === undefined ? _b_.hash(key) : $hash,
666
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
667
668
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
669
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
673
var sk = self.$str_hash[hash]
674
if(sk !== undefined && _eq(sk)){
675
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
680
// If $setitem is called from setdefault, don't test equality of key
681
// with any object
682
if($hash){
683
if(self.$object_dict[$hash] !== undefined){
684
self.$object_dict[$hash].push([key, [value, self.$version]])
686
self.$object_dict[$hash] = [[key, [value, self.$version]]]
687
}
688
self.$version++
689
return $N
690
}
691
var ix = rank(self, hash, key)
692
if(ix > -1){
693
// reset value
694
self.$object_dict[hash][ix][1] = [value,
695
self.$object_dict[hash][ix][1][1]]
696
return $N
697
}else if(self.$object_dict.hasOwnProperty(hash)){
698
self.$object_dict[hash].push([key, [value, self.$version]])
700
self.$object_dict[hash] = [[key, [value, self.$version]]]
Sep 5, 2014
704
}
705
706
dict.__str__ = function(){
707
return dict.__repr__.apply(null, arguments)
708
}
Sep 5, 2014
709
710
// add "reflected" methods
Feb 11, 2018
711
$B.make_rmethods(dict)
Sep 5, 2014
712
Feb 11, 2018
713
dict.clear = function(){
Sep 5, 2014
714
// Remove all items from the dictionary.
Mar 7, 2018
715
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
716
null, null),
717
self = $.self
719
self.$numeric_dict = {}
720
self.$string_dict = {}
721
self.$str_hash = {}
722
self.$object_dict = {}
724
if(self.$jsobj){
725
for(var attr in self.$jsobj){
Mar 7, 2018
726
if(attr.charAt(0) !== "$" && attr !== "__class__"){
727
delete self.$jsobj[attr]
728
}
729
}
730
}
Sep 5, 2014
733
}
734
Feb 11, 2018
735
dict.copy = function(self){
Sep 5, 2014
736
// Return a shallow copy of the dictionary
Mar 7, 2018
737
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
738
null, null),
739
self = $.self,
Feb 11, 2018
740
res = _b_.dict.$factory()
Sep 5, 2014
742
return res
743
}
744
Feb 11, 2018
745
dict.fromkeys = function(){
Nov 21, 2015
746
Mar 7, 2018
747
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
748
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
749
keys = $.keys,
750
value = $.value
Sep 5, 2014
752
// class method
753
var klass = $.cls,
Sep 5, 2014
757
while(1){
758
try{
759
var key = _b_.next(keys_iter)
760
if(klass === dict){dict.$setitem(res, key, value)}
761
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
762
}catch(err){
763
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
764
return res
765
}
766
throw err
767
}
768
}
769
}
770
Feb 11, 2018
771
dict.get = function(){
Mar 7, 2018
772
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
773
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
775
try{return dict.__getitem__($.self, $.key)}
776
catch(err){
777
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
778
else{throw err}
779
}
780
}
781
782
var dict_items = $B.make_view("dict_items", true)
783
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
784
Feb 11, 2018
785
dict.items = function(self){
Mar 23, 2018
786
if(arguments.length > 1){
787
var _len = arguments.length - 1,
788
_msg = "items() takes no arguments (" + _len + " given)"
789
throw _b_.TypeError.$factory(_msg)
790
}
791
var it = dict_items.$factory(to_list(self))
792
it.len_func = function(){return dict.__len__(self)}
793
return it
794
}
795
796
var dict_keys = $B.make_view("dict_keys", true)
797
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
798
Mar 23, 2018
800
if(arguments.length > 1){
801
var _len = arguments.length - 1,
802
_msg = "keys() takes no arguments (" + _len + " given)"
803
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
804
}
805
var it = dict_keys.$factory(to_list(self, 0))
806
it.len_func = function(){return dict.__len__(self)}
807
return it
Nov 21, 2015
808
}
809
Feb 11, 2018
810
dict.pop = function(){
Nov 21, 2015
811
812
var missing = {},
813
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
814
["self", "key", "_default"], arguments, {_default: missing}, null, null),
815
self = $.self,
816
key = $.key,
817
_default = $._default
Nov 21, 2015
818
Sep 5, 2014
819
try{
820
var res = dict.__getitem__(self, key)
821
dict.__delitem__(self, key)
Sep 5, 2014
822
return res
823
}catch(err){
824
if(err.__class__ === _b_.KeyError){
825
if(_default !== missing){return _default}
Sep 5, 2014
826
throw err
827
}
828
throw err
829
}
830
}
831
Feb 11, 2018
832
dict.popitem = function(self){
834
var itm = _b_.next(_b_.iter(dict.items(self)))
835
dict.__delitem__(self, itm[0])
Feb 11, 2018
836
return _b_.tuple.$factory(itm)
838
if (err.__class__ == _b_.StopIteration) {
839
throw KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
842
}
843
Feb 11, 2018
844
dict.setdefault = function(){
Nov 21, 2015
845
Mar 7, 2018
846
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
847
["self", "key", "_default"], arguments, {_default: $N}, null, null),
848
self = $.self,
849
key = $.key,
850
_default = $._default
Nov 21, 2015
851
852
try{return dict.__getitem__(self, key)}
Sep 5, 2014
853
catch(err){
854
if(err.__class__ !== _b_.KeyError){
855
throw err
856
}
857
if(_default === undefined){_default = $N}
858
var hash = key.$hash
859
key.$hash = undefined
860
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
861
return _default
862
}
863
}
864
Feb 11, 2018
865
dict.update = function(self){
Nov 21, 2015
866
Mar 7, 2018
867
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
868
{}, "args", "kw"),
869
self = $.self,
870
args = $.args,
871
kw = $.kw
872
if(args.length > 0){
873
var o = args[0]
874
if(isinstance(o, dict)){
875
if(o.$jsobj){
876
o = jsobj2dict(o.$jsobj)
877
}
880
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
881
for(var i = 0, len = _keys.length; i < len; i++){
882
var _value = getattr(o, "__getitem__")(_keys[i])
883
dict.$setitem(self, _keys[i], _value)
884
}
885
}else{
886
var it = _b_.iter(o),
887
i = 0
888
while(true){
889
try{
890
var item = _b_.next(it)
891
}catch(err){
892
if(err.__class__ === _b_.StopIteration){break}
893
throw err
894
}
895
try{
896
key_value = _b_.list.$factory(item)
897
}catch(err){
898
throw _b_.TypeError.$factory("cannot convert dictionary" +
899
" update sequence element #" + i + " to a sequence")
900
}
901
if(key_value.length !== 2){
902
throw _b_.ValueError.$factory("dictionary update " +
903
"sequence element #" + i + " has length " +
904
key_value.length + "; 2 is required")
905
}
906
dict.$setitem(self, key_value[0], key_value[1])
907
i++
Sep 5, 2014
910
}
Sep 5, 2014
914
}
915
916
var dict_values = $B.make_view("dict_values")
917
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
918
Feb 11, 2018
919
dict.values = function(self){
Mar 23, 2018
920
if(arguments.length > 1){
921
var _len = arguments.length - 1,
922
_msg = "values() takes no arguments (" + _len + " given)"
923
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
924
}
925
var it = dict_values.$factory(to_list(self, 1))
926
it.len_func = function(){return dict.__len__(self)}
927
return it
Nov 21, 2015
928
}
929
930
dict.$factory = function(){
931
var res = dict.__new__(dict)
932
var args = [res]
933
for(var i = 0, len = arguments.length; i < len ; i++){
934
args.push(arguments[i])
935
}
936
dict.__init__.apply(null, args)
Sep 5, 2014
937
return res
938
}
Sep 5, 2014
940
_b_.dict = dict
Feb 11, 2018
942
$B.set_func_names(dict, "builtins")
944
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
945
// have the attribute $infos
946
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
947
948
$B.getset_descriptor = $B.make_class("getset_descriptor",
949
function(klass, attr){
950
return {
951
__class__: $B.getset_descriptor,
952
cls: klass,
953
attr: attr
954
}
955
}
956
)
957
958
$B.getset_descriptor.__repr__ = $B.getset_descriptor.__str__ = function(self){
959
return `<attribute '${self.attr}' of '${self.cls.$infos.__name__}' objects>`
960
}
961
962
$B.set_func_names($B.getset_descriptor, "builtins")
963
964
// Class for attribute __dict__ of classes
965
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
966
function(obj){
967
if(_b_.isinstance(obj, dict)){
968
// obj is a dictionary, with $string_dict table such that
969
// obj.$string_dict[key] = [value, rank]
970
// Transform it into an object with attribute $jsobj such that
971
// res.$jsobj[key] = value
972
var res = $B.obj_dict(dict.$to_obj(obj))
973
}else{
974
var res = $B.obj_dict(obj)
975
}
Feb 12, 2018
976
res.__class__ = mappingproxy
977
return res
978
}
979
)
Feb 12, 2018
981
mappingproxy.__setitem__ = function(){
Mar 7, 2018
982
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
983
"item assignment")
986
for(var attr in dict){
987
if(mappingproxy[attr] !== undefined ||
988
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
989
"clear", "fromkeys", "pop", "popitem", "setdefault",
990
"update"].indexOf(attr) > -1){
991
continue
992
}
993
if(typeof dict[attr] == "function"){
994
mappingproxy[attr] = (function(key){
995
return function(){
996
return dict[key].apply(null, arguments)
997
}
998
})(attr)
999
}else{
1000
mappingproxy[attr] = dict[attr]
1001
}
1002
}
1003
Feb 12, 2018
1004
$B.set_func_names(mappingproxy, "builtins")
Feb 11, 2018
1007
var d = dict.$factory()
Mar 7, 2018
1009
if(attr.charAt(0) != "$" && attr !== "__class__"){
1010
if(x[attr] === null){
1011
d.$string_dict[attr] = [_b_.None, d.$version]
1012
}else if(x[attr] === undefined){
1013
continue
1014
}else if(x[attr].$jsobj === x){
1015
d.$string_dict[attr] = [d, d.$version]
1017
d.$string_dict[attr] = [$B.$JS2Py(x[attr]), d.$version]
1019
d.$version++
1020
}
1021
}
1022
return d
1023
}
1025
$B.obj_dict = function(obj, from_js){
1026
var klass = obj.__class__ || $B.get_class(obj)
1027
if(klass !== undefined && klass.$native){
1028
throw _b_.AttributeError.$factory(klass.__name__ +
1029
" has no attribute '__dict__'")}
Feb 11, 2018
1030
var res = dict.$factory()
1031
res.$jsobj = obj
1032
res.$from_js = from_js // set to true if
1033
return res
1034
}
1035
Sep 5, 2014
1036
})(__BRYTHON__)