Skip to content
Permalink
Newer
Older
100644 1007 lines (900 sloc) 29.9 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
klass.__repr__ = function(self){
66
return klass.$infos.__name__ + '(' + _b_.repr(self.items) + ')'
67
}
68
69
$B.set_func_names(klass, "builtins")
70
return klass
71
}
72
73
// Special version of __next__ for iterators on dict keys / values / items.
74
// Checks that the dictionary size didn't change during iteration.
75
function dict_iterator_next(self){
76
if(self.len_func() != self.len){
77
throw RuntimeError.$factory("dictionary changed size during iteration")
78
}
79
self.counter++
80
if(self.counter < self.items.length){
81
return self.items[self.counter]
82
}
83
throw _b_.StopIteration.$factory("StopIteration")
84
}
85
Feb 11, 2018
86
var dict = {
Feb 11, 2018
87
__class__: _b_.type,
88
__mro__: [object],
89
$infos: {
90
__module__: "builtins",
91
__name__: "dict"
92
},
Feb 11, 2018
93
$is_class: true,
94
$native: true
Sep 5, 2014
95
}
96
97
dict.$to_obj = function(d){
98
// Function applied to dictionary that only have string keys,
99
// return a Javascript objects with the kays mapped to the value,
100
// excluding the insertion rank
101
var res = {}
102
for(var key in d.$string_dict){
103
res[key] = d.$string_dict[key][0]
104
}
105
return res
106
}
107
108
function to_list(d, ix){
109
var items = [],
110
item
112
if(d.$jsobj){
Mar 7, 2018
115
if(attr.charAt(0) != "$"){
116
var val = d.$jsobj[attr]
117
if(val === undefined){val = _b_.NotImplemented}
118
else if(val === null){val = $N}
122
}else{
123
for(var k in d.$numeric_dict){
124
items.push([parseFloat(k), d.$numeric_dict[k]])
125
}
127
for(var k in d.$string_dict){items.push([k, d.$string_dict[k]])}
129
for(var k in d.$object_dict){
130
d.$object_dict[k].forEach(function(item){
131
items.push(item)
132
})
133
}
134
// sort by insertion order
135
items.sort(function(a, b){
136
return a[1][1] - b[1][1]
137
})
138
items = items.map(function(item){return [item[0], item[1][0]]})
141
if(ix !== undefined){
142
return items.map(function(item){return item[ix]})
143
}else{
144
items.__class__ = _b_.tuple
145
return items.map(function(item){
146
item.__class__ = _b_.tuple; return item}
147
)
148
}
Feb 9, 2015
150
151
$B.dict_to_list = to_list // used in py_types.js
152
153
// Special version of __next__ for iterators on dict keys / values / items.
154
// Checks that the dictionary size didn't change during iteration.
155
function dict_iterator_next(self){
156
if(self.len_func() != self.len){
157
throw RuntimeError.$factory("dictionary changed size during iteration")
158
}
159
self.counter++
160
if(self.counter < self.items.length){
161
return self.items[self.counter]
163
throw _b_.StopIteration.$factory("StopIteration")
167
var $copy_dict = function(left, right){
169
si = dict.$setitem
170
right.$version = right.$version || 0
171
var right_version = right.$version || 0
172
for(var i = 0, len = _l.length; i < len; i++){
173
si(left, _l[i][0], _l[i][1])
174
if(right.$version != right_version){
175
throw _b_.RuntimeError.$factory("dict mutated during update")
176
}
177
}
180
function rank(self, hash, key){
181
// Search if object key, with hash = hash(key), is in
182
// self.$object_dict
183
var pairs = self.$object_dict[hash]
184
if(pairs !== undefined){
185
for(var i = 0, len = pairs.length; i < len; i++){
186
if($B.rich_comp("__eq__", key, pairs[i][0])){
187
return i
188
}
189
}
190
}
191
return -1
192
}
193
Feb 11, 2018
194
dict.__bool__ = function () {
Mar 7, 2018
195
var $ = $B.args("__bool__", 1, {self: null}, ["self"],
196
arguments, {}, null, null)
Feb 11, 2018
197
return dict.__len__($.self) > 0
Feb 11, 2018
200
dict.__contains__ = function(){
Nov 21, 2015
201
202
var $ = $B.args("__contains__", 2, {self: null, key: null},
203
["self", "key"], arguments, {}, null, null),
204
self = $.self,
206
if(self.$is_namespace){key = $B.to_alias(key)} // issue 1244
207
208
if(self.$jsobj){
209
return self.$jsobj[key] !== undefined
210
}
212
switch(typeof key) {
214
return self.$string_dict[key] !== undefined
216
return self.$numeric_dict[key] !== undefined
217
}
218
219
var hash = _b_.hash(key)
220
if(self.$str_hash[hash] !== undefined &&
221
$B.rich_comp("__eq__", key, self.$str_hash[hash])){return true}
222
if(self.$numeric_dict[hash] !== undefined &&
223
$B.rich_comp("__eq__", key, hash)){return true}
224
return rank(self, hash, key) > -1
Sep 5, 2014
225
}
226
Feb 11, 2018
227
dict.__delitem__ = function(){
Nov 21, 2015
228
229
var $ = $B.args("__eq__", 2, {self: null, arg: null},
230
["self", "arg"], arguments, {}, null, null),
231
self = $.self,
Nov 21, 2015
233
234
if(self.$jsobj){
235
if(self.$jsobj[arg] === undefined){throw KeyError.$factory(arg)}
236
delete self.$jsobj[arg]
239
switch(typeof arg){
240
case "string":
241
if(self.$string_dict[arg] === undefined){
242
throw KeyError.$factory(_b_.str.$factory(arg))
243
}
244
delete self.$string_dict[arg]
245
delete self.$str_hash[str_hash(arg)]
247
return $N
248
case "number":
249
if(self.$numeric_dict[arg] === undefined){
250
throw KeyError.$factory(_b_.str.$factory(arg))
252
delete self.$numeric_dict[arg]
256
// go with defaults
257
258
var hash = _b_.hash(arg),
259
ix
261
if((ix = rank(self, hash, arg)) > -1){
262
self.$object_dict[hash].splice(ix, 1)
263
}else{
264
throw KeyError.$factory(_b_.str.$factory(arg))
Sep 5, 2014
269
}
270
Feb 11, 2018
271
dict.__eq__ = function(){
Mar 7, 2018
272
var $ = $B.args("__eq__", 2, {self: null, other: null},
273
["self", "other"], arguments, {}, null, null),
274
self = $.self,
275
other = $.other
Mar 7, 2018
277
if(! isinstance(other, dict)){return false}
279
if(self.$jsobj){self = jsobj2dict(self.$jsobj)}
280
if(other.$jsobj){other = jsobj2dict(other.$jsobj)}
281
if(dict.__len__(self) != dict.__len__(other)){
282
return false
283
}
285
if(self.$string_dict.length != other.$string_dict.length){
289
for(var k in self.$numeric_dict){
290
if(other.$numeric_dict.hasOwnProperty(k)){
291
if(!$B.rich_comp("__eq__", other.$numeric_dict[k][0],
292
self.$numeric_dict[k][0])){
293
return false
294
}
295
}else if(other.$object_dict.hasOwnProperty(k)){
296
var pairs = other.$object_dict[k],
297
flag = false
298
for(var i = 0, len = pairs.length; i < len; i++){
299
if($B.rich_comp("__eq__", k, pairs[i][0]) &&
300
$B.rich_comp("__eq__", self.$numeric_dict[k],
301
pairs[i][1])){
302
flag = true
303
break
304
}
306
if(! flag){return false}
Nov 21, 2015
309
}
310
}
311
for(var k in self.$string_dict){
312
if(!other.$string_dict.hasOwnProperty(k) ||
313
!$B.rich_comp("__eq__", other.$string_dict[k][0],
314
self.$string_dict[k][0])){
Nov 21, 2015
316
}
317
}
318
for(var hash in self.$object_dict){
319
var pairs = self.$object_dict[hash]
320
// Get all (key, value) pairs in other that have the same hash
321
var other_pairs = []
322
if(other.$numeric_dict[hash] !== undefined){
323
other_pairs.push([hash, other.$numeric_dict[hash]])
324
}
325
if(other.$object_dict[hash] !== undefined){
326
other_pairs = other_pairs.concat(other.$object_dict[hash])
327
}
328
if(other_pairs.length == 0){
329
return false
330
}
331
for(var i = 0, len_i = pairs.length; i < len_i; i++){
332
var flag = false
333
var key = pairs[i][0],
334
value = pairs[i][1][0]
335
for(var j = 0, len_j = other_pairs.length; j < len_j; j++){
336
if($B.rich_comp("__eq__", key, other_pairs[j][0]) &&
337
$B.rich_comp("__eq__", value, other_pairs[j][1][0])){
338
flag = true
339
break
345
}
346
}
347
return true
Sep 5, 2014
348
}
349
Feb 11, 2018
350
dict.__getitem__ = function(){
351
var $ = $B.args("__getitem__", 2, {self: null, arg: null},
352
["self", "arg"], arguments, {}, null, null),
353
self = $.self,
355
return dict.$getitem(self, arg)
356
}
357
358
dict.$getitem = function(self, arg){
359
if(self.$jsobj){
360
if(!self.$jsobj.hasOwnProperty(arg)){
361
throw _b_.KeyError.$factory(str.$factory(arg))
362
}else if(self.$jsobj[arg] === undefined){
363
return _b_.NotImplemented
364
}else if(self.$jsobj[arg] === null){return $N}
365
return self.$jsobj[arg]
367
368
switch(typeof arg){
369
case "string":
370
if(self.$string_dict[arg] !== undefined){
371
return self.$string_dict[arg][0]
373
break
374
case "number":
375
if(self.$numeric_dict[arg] !== undefined){
376
return self.$numeric_dict[arg][0]
378
break
379
}
380
381
// since the key is more complex use 'default' method of getting item
382
383
var hash = _b_.hash(arg),
384
_eq = function(other){return $B.rich_comp("__eq__", arg, other)}
385
386
if(typeof arg == "object"){
387
arg.$hash = hash // cache for setdefault
388
}
389
var sk = self.$str_hash[hash]
390
if(sk !== undefined && _eq(sk)){
391
return self.$string_dict[sk][0]
393
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
394
return self.$numeric_dict[hash][0]
395
}
396
if(isinstance(arg, _b_.str)){
397
// string subclass
398
var res = self.$string_dict[arg.valueOf()]
399
if(res !== undefined){return res[0]}
402
var ix = rank(self, hash, arg)
403
if(ix > -1){
404
return self.$object_dict[hash][ix][1][0]
407
if(self.__class__ !== dict){
409
var missing_method = getattr(self.__class__, "__missing__",
410
_b_.None)
411
}catch(err){
412
console.log(err)
413
414
}
415
if(missing_method !== _b_.None){
416
return missing_method(self, arg)
Sep 5, 2014
420
}
421
422
dict.__hash__ = _b_.None
Sep 5, 2014
423
424
function init_from_list(self, args){
425
var i = -1,
426
stop = args.length - 1,
427
si = dict.__setitem__
428
while(i++ < stop){
429
var item = args[i]
430
switch(typeof item[0]) {
431
case 'string':
432
self.$string_dict[item[0]] = [item[1], self.$version]
433
self.$str_hash[str_hash(item[0])] = item[0]
434
self.$version++
435
break
436
case 'number':
437
self.$numeric_dict[item[0]] = [item[1], self.$version]
438
self.$version++
439
break
440
default:
441
si(self, item[0], item[1])
442
break
443
}
444
}
445
}
446
447
dict.__init__ = function(self, first, second){
449
if(first === undefined){return $N}
450
if(second === undefined){
451
if(first.__class__ === $B.JSObject){
452
self.$jsobj = first.js
453
return $N
454
}else if(first.$jsobj){
455
self.$jsobj = {}
456
for(var attr in first.$jsobj){
457
self.$jsobj[attr] = first.$jsobj[attr]
460
}else if(Array.isArray(first)){
461
init_from_list(self, first)
462
return $N
Sep 5, 2014
463
}
466
$ = $ || $B.args("dict", 1, {self:null}, ["self"],
467
arguments, {}, "first", "second")
468
var args = $.first
469
if(args.length > 1){
470
throw _b_.TypeError.$factory("dict expected at most 1 argument" +
471
", got 2")
472
}else if(args.length == 1){
473
args = args[0]
474
if(args.__class__ === dict){
475
['$string_dict', '$str_hash', '$numeric_dict', '$object_dict'].
476
forEach(function(d){
477
for(key in args[d]){self[d][key] = args[d][key]}
478
})
479
}else if(isinstance(args, dict)){
480
$copy_dict(self, args)
482
var keys = $B.$getattr(args, "keys", null)
483
if(keys !== null){
484
var gi = $B.$getattr(args, "__getitem__", null)
485
if(gi !== null){
486
// has keys and __getitem__ : it's a mapping, iterate on
487
// keys and values
488
gi = $B.$call(gi)
489
var kiter = _b_.iter($B.$call(keys)())
490
while(true){
491
try{
492
var key = _b_.next(kiter),
493
value = gi(key)
494
dict.__setitem__(self, key, value)
495
}catch(err){
496
if(err.__class__ === _b_.StopIteration){
497
break
498
}
499
throw err
500
}
501
}
502
return $N
503
}
504
}
505
if(! Array.isArray(args)){
506
args = _b_.list.$factory(args)
507
}
508
// Form "dict([[key1, value1], [key2,value2], ...])"
509
init_from_list(self, args)
Sep 5, 2014
510
}
512
var kw = $.second.$string_dict
513
for(var attr in kw){
514
switch(typeof attr){
515
case "string":
516
self.$string_dict[attr] = kw[attr]
517
self.$str_hash[str_hash(attr)] = attr
518
break
519
case "number":
520
self.$numeric_dict[attr] = kw[attr]
521
break
522
default:
523
si(self, attr, kw[attr])
524
break
525
}
Sep 5, 2014
528
}
529
Feb 11, 2018
530
dict.__iter__ = function(self) {
531
return _b_.iter(dict.$$keys(self))
Sep 5, 2014
532
}
533
Feb 11, 2018
534
dict.__len__ = function(self) {
537
if(self.$jsobj){
Mar 7, 2018
538
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
539
return _count
540
}
542
for(var k in self.$numeric_dict){_count++}
543
for(var k in self.$string_dict){_count++}
544
for(var hash in self.$object_dict){
545
_count += self.$object_dict[hash].length
546
}
Sep 5, 2014
550
Mar 7, 2018
551
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
552
Feb 11, 2018
553
dict.__new__ = function(cls){
554
if(cls === undefined){
Mar 7, 2018
555
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
557
var instance = {
559
$numeric_dict : {},
560
$object_dict : {},
562
$str_hash: {},
563
$version: 0
565
if(cls !== dict){
566
instance.__dict__ = _b_.dict.$factory()
567
}
568
return instance
Feb 11, 2018
571
dict.__repr__ = function(self){
572
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
573
return dict.__repr__(jsobj2dict(self.$jsobj))
575
var res = [],
577
items.forEach(function(item){
578
if((!self.$jsobj && item[1] === self) ||
579
(self.$jsobj && item[1] === self.$jsobj)){
Mar 7, 2018
580
res.push(repr(item[0]) + ": {...}")
582
res.push(repr(item[0]) + ": " + repr(item[1]))
Mar 7, 2018
585
return "{" + res.join(", ") + "}"
Sep 5, 2014
586
}
587
588
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
589
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
590
["self", "key", "value"], arguments, {}, null, null)
591
return dict.$setitem($.self, $.key, $.value)
592
}
Nov 21, 2015
593
594
dict.$setitem = function(self, key, value, $hash){
595
// Set a dictionary item mapping key and value.
596
//
597
// If key is a string, set $string_dict[key] = value and
598
// $str_hash[hash(key)] to key
599
//
600
// If key is a number, set $numeric_dict[key] = value
601
//
602
// If key is another object, compute its hash value:
603
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
604
// replace $string_dict[$str_hash[hash]] by value
605
// - if the hash is a key of $numeric_dict, and hash == key, replace
606
// $numeric_dict[hash] by value
607
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
608
// of [k, v] pairs. If key is equal to one of the "k", replace the
609
// matching v by value. Otherwise, add [key, value] to the list
610
// - else set $object_dict[hash] = [[key, value]]
611
//
612
// In all cases, increment attribute $version, used to detect dictionary
613
// cahnges during an iteration.
614
//
615
// Parameter $hash is only set if this method is called by setdefault.
616
// In this case the hash of key has already been computed and we
617
// know that the key is not present in the dictionary, so it's no
618
// use computing hash(key) again, nor testing equality of keys
620
if(self.$from_js){
621
// dictionary created by method to_dict of JSObject instances
622
value = $B.pyobj2jsobj(value)
623
}
624
if(self.$jsobj.__class__ === _b_.type){
625
self.$jsobj[key] = value
626
if(key == "__init__" || key == "__new__"){
627
// If class attribute __init__ or __new__ are reset,
628
// the factory function has to change
629
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
630
}
631
}else{
632
self.$jsobj[key] = value
637
switch(typeof key){
638
case "string":
639
if(self.$string_dict === undefined){
640
console.log("pas de string dict", self, key, value)
641
}
642
self.$string_dict[key] = [value, self.$version]
643
self.$str_hash[str_hash(key)] = key
645
return $N
646
case "number":
647
self.$numeric_dict[key] = [value, self.$version]
649
return $N
652
// if we got here the key is more complex, use default method
653
654
var hash = $hash === undefined ? _b_.hash(key) : $hash,
655
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
656
657
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
658
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
662
var sk = self.$str_hash[hash]
663
if(sk !== undefined && _eq(sk)){
664
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
669
// If $setitem is called from setdefault, don't test equality of key
670
// with any object
671
if($hash){
672
if(self.$object_dict[$hash] !== undefined){
673
self.$object_dict[$hash].push([key, [value, self.$version]])
675
self.$object_dict[$hash] = [[key, [value, self.$version]]]
676
}
677
self.$version++
678
return $N
679
}
680
var ix = rank(self, hash, key)
681
if(ix > -1){
682
// reset value
683
self.$object_dict[hash][ix][1] = [value,
684
self.$object_dict[hash][ix][1][1]]
685
return $N
686
}else if(self.$object_dict.hasOwnProperty(hash)){
687
self.$object_dict[hash].push([key, [value, self.$version]])
689
self.$object_dict[hash] = [[key, [value, self.$version]]]
Sep 5, 2014
693
}
694
695
dict.__str__ = function(){
696
return dict.__repr__.apply(null, arguments)
697
}
Sep 5, 2014
698
699
// add "reflected" methods
Feb 11, 2018
700
$B.make_rmethods(dict)
Sep 5, 2014
701
Feb 11, 2018
702
dict.clear = function(){
Sep 5, 2014
703
// Remove all items from the dictionary.
Mar 7, 2018
704
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
705
null, null),
706
self = $.self
708
self.$numeric_dict = {}
709
self.$string_dict = {}
710
self.$str_hash = {}
711
self.$object_dict = {}
713
if(self.$jsobj){
714
for(var attr in self.$jsobj){
Mar 7, 2018
715
if(attr.charAt(0) !== "$" && attr !== "__class__"){
716
delete self.$jsobj[attr]
717
}
718
}
719
}
Sep 5, 2014
722
}
723
Feb 11, 2018
724
dict.copy = function(self){
Sep 5, 2014
725
// Return a shallow copy of the dictionary
Mar 7, 2018
726
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
727
null, null),
728
self = $.self,
Feb 11, 2018
729
res = _b_.dict.$factory()
Sep 5, 2014
731
return res
732
}
733
Feb 11, 2018
734
dict.fromkeys = function(){
Nov 21, 2015
735
Mar 7, 2018
736
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
737
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
738
keys = $.keys,
739
value = $.value
Sep 5, 2014
741
// class method
742
var klass = $.cls,
Sep 5, 2014
746
while(1){
747
try{
748
var key = _b_.next(keys_iter)
749
if(klass === dict){dict.$setitem(res, key, value)}
750
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
751
}catch(err){
752
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
753
return res
754
}
755
throw err
756
}
757
}
758
}
759
Feb 11, 2018
760
dict.get = function(){
Mar 7, 2018
761
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
762
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
764
try{return dict.__getitem__($.self, $.key)}
765
catch(err){
766
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
767
else{throw err}
768
}
769
}
770
771
var dict_items = $B.make_view("dict_items", true)
772
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
773
Feb 11, 2018
774
dict.items = function(self){
Mar 23, 2018
775
if(arguments.length > 1){
776
var _len = arguments.length - 1,
777
_msg = "items() takes no arguments (" + _len + " given)"
778
throw _b_.TypeError.$factory(_msg)
779
}
780
var it = dict_items.$factory(to_list(self))
781
it.len_func = function(){return dict.__len__(self)}
782
return it
783
}
784
785
var dict_keys = $B.make_view("dict_keys", true)
786
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
787
Mar 23, 2018
789
if(arguments.length > 1){
790
var _len = arguments.length - 1,
791
_msg = "keys() takes no arguments (" + _len + " given)"
792
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
793
}
794
var it = dict_keys.$factory(to_list(self, 0))
795
it.len_func = function(){return dict.__len__(self)}
796
return it
Nov 21, 2015
797
}
798
Feb 11, 2018
799
dict.pop = function(){
Nov 21, 2015
800
801
var missing = {},
802
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
803
["self", "key", "_default"], arguments, {_default: missing}, null, null),
804
self = $.self,
805
key = $.key,
806
_default = $._default
Nov 21, 2015
807
Sep 5, 2014
808
try{
809
var res = dict.__getitem__(self, key)
810
dict.__delitem__(self, key)
Sep 5, 2014
811
return res
812
}catch(err){
813
if(err.__class__ === _b_.KeyError){
814
if(_default !== missing){return _default}
Sep 5, 2014
815
throw err
816
}
817
throw err
818
}
819
}
820
Feb 11, 2018
821
dict.popitem = function(self){
823
var itm = _b_.next(_b_.iter(dict.items(self)))
824
dict.__delitem__(self, itm[0])
Feb 11, 2018
825
return _b_.tuple.$factory(itm)
827
if (err.__class__ == _b_.StopIteration) {
828
throw KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
831
}
832
Feb 11, 2018
833
dict.setdefault = function(){
Nov 21, 2015
834
Mar 7, 2018
835
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
836
["self", "key", "_default"], arguments, {_default: $N}, null, null),
837
self = $.self,
838
key = $.key,
839
_default = $._default
Nov 21, 2015
840
841
try{return dict.__getitem__(self, key)}
Sep 5, 2014
842
catch(err){
843
if(err.__class__ !== _b_.KeyError){
844
throw err
845
}
846
if(_default === undefined){_default = $N}
847
var hash = key.$hash
848
key.$hash = undefined
849
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
850
return _default
851
}
852
}
853
Feb 11, 2018
854
dict.update = function(self){
Nov 21, 2015
855
Mar 7, 2018
856
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
857
{}, "args", "kw"),
858
self = $.self,
859
args = $.args,
860
kw = $.kw
861
if(args.length > 0){
862
var o = args[0]
863
if(isinstance(o, dict)){
864
if(o.$jsobj){
865
o = jsobj2dict(o.$jsobj)
866
}
869
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
870
for(var i = 0, len = _keys.length; i < len; i++){
871
var _value = getattr(o, "__getitem__")(_keys[i])
872
dict.$setitem(self, _keys[i], _value)
873
}
874
}else{
875
var it = _b_.iter(o),
876
i = 0
877
while(true){
878
try{
879
var item = _b_.next(it)
880
}catch(err){
881
if(err.__class__ === _b_.StopIteration){break}
882
throw err
883
}
884
try{
885
key_value = _b_.list.$factory(item)
886
}catch(err){
887
throw _b_.TypeError.$factory("cannot convert dictionary" +
888
" update sequence element #" + i + " to a sequence")
889
}
890
if(key_value.length !== 2){
891
throw _b_.ValueError.$factory("dictionary update " +
892
"sequence element #" + i + " has length " +
893
key_value.length + "; 2 is required")
894
}
895
dict.$setitem(self, key_value[0], key_value[1])
896
i++
Sep 5, 2014
899
}
Sep 5, 2014
903
}
904
905
var dict_values = $B.make_view("dict_values")
906
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
907
Feb 11, 2018
908
dict.values = function(self){
Mar 23, 2018
909
if(arguments.length > 1){
910
var _len = arguments.length - 1,
911
_msg = "values() takes no arguments (" + _len + " given)"
912
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
913
}
914
var it = dict_values.$factory(to_list(self, 1))
915
it.len_func = function(){return dict.__len__(self)}
916
return it
Nov 21, 2015
917
}
918
919
dict.$factory = function(){
920
var res = dict.__new__(dict)
921
var args = [res]
922
for(var i = 0, len = arguments.length; i < len ; i++){
923
args.push(arguments[i])
924
}
925
dict.__init__.apply(null, args)
Sep 5, 2014
926
return res
927
}
Sep 5, 2014
929
_b_.dict = dict
Feb 11, 2018
931
$B.set_func_names(dict, "builtins")
933
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
934
// have the attribute $infos
935
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
936
937
// Class for attribute __dict__ of classes
938
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
939
function(obj){
940
if(_b_.isinstance(obj, dict)){
941
// obj is a dictionary, with $string_dict table such that
942
// obj.$string_dict[key] = [value, rank]
943
// Transform it into an object with attribute $jsobj such that
944
// res.$jsobj[key] = value
945
var res = $B.obj_dict(dict.$to_obj(obj))
946
}else{
947
var res = $B.obj_dict(obj)
948
}
Feb 12, 2018
949
res.__class__ = mappingproxy
950
return res
951
}
952
)
Feb 12, 2018
954
mappingproxy.__setitem__ = function(){
Mar 7, 2018
955
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
956
"item assignment")
959
for(var attr in dict){
960
if(mappingproxy[attr] !== undefined ||
961
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
962
"clear", "fromkeys", "pop", "popitem", "setdefault",
963
"update"].indexOf(attr) > -1){
964
continue
965
}
966
if(typeof dict[attr] == "function"){
967
mappingproxy[attr] = (function(key){
968
return function(){
969
return dict[key].apply(null, arguments)
970
}
971
})(attr)
972
}else{
973
mappingproxy[attr] = dict[attr]
974
}
975
}
976
Feb 12, 2018
977
$B.set_func_names(mappingproxy, "builtins")
Feb 11, 2018
980
var d = dict.$factory()
Mar 7, 2018
982
if(attr.charAt(0) != "$" && attr !== "__class__"){
983
if(x[attr] === undefined){
984
continue
985
}else if(x[attr].$jsobj === x){
986
d.$string_dict[attr] = [d, d.$version]
988
d.$string_dict[attr] = [x[attr], d.$version]
990
d.$version++
996
$B.obj_dict = function(obj, from_js){
997
var klass = obj.__class__ || $B.get_class(obj)
998
if(klass !== undefined && klass.$native){
999
throw _b_.AttributeError.$factory(klass.__name__ +
1000
" has no attribute '__dict__'")}
Feb 11, 2018
1001
var res = dict.$factory()
1002
res.$jsobj = obj
1003
res.$from_js = from_js // set to true if
1004
return res
1005
}
1006
Sep 5, 2014
1007
})(__BRYTHON__)