Skip to content
Permalink
Newer
Older
100644 1011 lines (902 sloc) 29.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)
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.hasOwnProperty(arg)){
366
throw _b_.KeyError.$factory(str.$factory(arg))
367
}else if(self.$jsobj[arg] === undefined){
368
return _b_.NotImplemented
369
}else if(self.$jsobj[arg] === null){return $N}
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]
400
}
401
if(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)
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.$version]
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.$version]
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(isinstance(args, dict)){
485
$copy_dict(self, args)
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]
522
self.$str_hash[str_hash(attr)] = attr
523
break
524
case "number":
525
self.$numeric_dict[attr] = kw[attr]
526
break
527
default:
528
si(self, attr, kw[attr])
529
break
530
}
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
Feb 11, 2018
539
dict.__len__ = function(self) {
542
if(self.$jsobj){
Mar 7, 2018
543
for(var attr in self.$jsobj){if(attr.charAt(0) != "$"){_count++}}
544
return _count
545
}
547
for(var k in self.$numeric_dict){_count++}
548
for(var k in self.$string_dict){_count++}
549
for(var hash in self.$object_dict){
550
_count += self.$object_dict[hash].length
551
}
Sep 5, 2014
555
Mar 7, 2018
556
dict.__ne__ = function(self, other){return ! dict.__eq__(self, other)}
Sep 5, 2014
557
Feb 11, 2018
558
dict.__new__ = function(cls){
559
if(cls === undefined){
Mar 7, 2018
560
throw _b_.TypeError.$factory("int.__new__(): not enough arguments")
562
var instance = {
564
$numeric_dict : {},
565
$object_dict : {},
567
$str_hash: {},
568
$version: 0
570
if(cls !== dict){
571
instance.__dict__ = _b_.dict.$factory()
572
}
573
return instance
Feb 11, 2018
576
dict.__repr__ = function(self){
577
if(self.$jsobj){ // wrapper around Javascript object
Feb 11, 2018
578
return dict.__repr__(jsobj2dict(self.$jsobj))
580
if($B.repr.enter(self)){
581
return "{...}"
582
}
583
var res = [],
585
items.forEach(function(item){
586
res.push(repr(item[0]) + ": " + repr(item[1]))
588
$B.repr.leave(self)
Mar 7, 2018
589
return "{" + res.join(", ") + "}"
Sep 5, 2014
590
}
591
592
dict.__setitem__ = function(self, key, value){
Mar 7, 2018
593
var $ = $B.args("__setitem__", 3, {self: null, key: null, value: null},
594
["self", "key", "value"], arguments, {}, null, null)
595
return dict.$setitem($.self, $.key, $.value)
596
}
Nov 21, 2015
597
598
dict.$setitem = function(self, key, value, $hash){
599
// Set a dictionary item mapping key and value.
600
//
601
// If key is a string, set $string_dict[key] = value and
602
// $str_hash[hash(key)] to key
603
//
604
// If key is a number, set $numeric_dict[key] = value
605
//
606
// If key is another object, compute its hash value:
607
// - if the hash is a key of $str_hash, and key == $str_hash[hash],
608
// replace $string_dict[$str_hash[hash]] by value
609
// - if the hash is a key of $numeric_dict, and hash == key, replace
610
// $numeric_dict[hash] by value
611
// - if the hash is a key of $object_dict: $object_dict[hash] is a list
612
// of [k, v] pairs. If key is equal to one of the "k", replace the
613
// matching v by value. Otherwise, add [key, value] to the list
614
// - else set $object_dict[hash] = [[key, value]]
615
//
616
// In all cases, increment attribute $version, used to detect dictionary
617
// cahnges during an iteration.
618
//
619
// Parameter $hash is only set if this method is called by setdefault.
620
// In this case the hash of key has already been computed and we
621
// know that the key is not present in the dictionary, so it's no
622
// use computing hash(key) again, nor testing equality of keys
624
if(self.$from_js){
625
// dictionary created by method to_dict of JSObject instances
626
value = $B.pyobj2jsobj(value)
627
}
628
if(self.$jsobj.__class__ === _b_.type){
629
self.$jsobj[key] = value
630
if(key == "__init__" || key == "__new__"){
631
// If class attribute __init__ or __new__ are reset,
632
// the factory function has to change
633
self.$jsobj.$factory = $B.$instance_creator(self.$jsobj)
634
}
635
}else{
636
self.$jsobj[key] = value
641
switch(typeof key){
642
case "string":
643
if(self.$string_dict === undefined){
644
console.log("pas de string dict", self, key, value)
645
}
646
self.$string_dict[key] = [value, self.$version]
647
self.$str_hash[str_hash(key)] = key
649
return $N
650
case "number":
651
self.$numeric_dict[key] = [value, self.$version]
653
return $N
656
// if we got here the key is more complex, use default method
657
658
var hash = $hash === undefined ? _b_.hash(key) : $hash,
659
_eq = function(other){return $B.rich_comp("__eq__", key, other)}
660
661
if(self.$numeric_dict[hash] !== undefined && _eq(hash)){
662
self.$numeric_dict[hash] = [value, self.$numeric_dict[hash][1]]
666
var sk = self.$str_hash[hash]
667
if(sk !== undefined && _eq(sk)){
668
self.$string_dict[sk] = [value, self.$string_dict[sk][1]]
673
// If $setitem is called from setdefault, don't test equality of key
674
// with any object
675
if($hash){
676
if(self.$object_dict[$hash] !== undefined){
677
self.$object_dict[$hash].push([key, [value, self.$version]])
679
self.$object_dict[$hash] = [[key, [value, self.$version]]]
680
}
681
self.$version++
682
return $N
683
}
684
var ix = rank(self, hash, key)
685
if(ix > -1){
686
// reset value
687
self.$object_dict[hash][ix][1] = [value,
688
self.$object_dict[hash][ix][1][1]]
689
return $N
690
}else if(self.$object_dict.hasOwnProperty(hash)){
691
self.$object_dict[hash].push([key, [value, self.$version]])
693
self.$object_dict[hash] = [[key, [value, self.$version]]]
Sep 5, 2014
697
}
698
699
dict.__str__ = function(){
700
return dict.__repr__.apply(null, arguments)
701
}
Sep 5, 2014
702
703
// add "reflected" methods
Feb 11, 2018
704
$B.make_rmethods(dict)
Sep 5, 2014
705
Feb 11, 2018
706
dict.clear = function(){
Sep 5, 2014
707
// Remove all items from the dictionary.
Mar 7, 2018
708
var $ = $B.args("clear", 1, {self: null}, ["self"], arguments, {},
709
null, null),
710
self = $.self
712
self.$numeric_dict = {}
713
self.$string_dict = {}
714
self.$str_hash = {}
715
self.$object_dict = {}
717
if(self.$jsobj){
718
for(var attr in self.$jsobj){
Mar 7, 2018
719
if(attr.charAt(0) !== "$" && attr !== "__class__"){
720
delete self.$jsobj[attr]
721
}
722
}
723
}
Sep 5, 2014
726
}
727
Feb 11, 2018
728
dict.copy = function(self){
Sep 5, 2014
729
// Return a shallow copy of the dictionary
Mar 7, 2018
730
var $ = $B.args("copy", 1, {self: null},["self"], arguments,{},
731
null, null),
732
self = $.self,
Feb 11, 2018
733
res = _b_.dict.$factory()
Sep 5, 2014
735
return res
736
}
737
Feb 11, 2018
738
dict.fromkeys = function(){
Nov 21, 2015
739
Mar 7, 2018
740
var $ = $B.args("fromkeys", 3, {cls: null, keys: null, value: null},
741
["cls", "keys", "value"], arguments, {value: _b_.None}, null, null),
742
keys = $.keys,
743
value = $.value
Sep 5, 2014
745
// class method
746
var klass = $.cls,
Sep 5, 2014
750
while(1){
751
try{
752
var key = _b_.next(keys_iter)
753
if(klass === dict){dict.$setitem(res, key, value)}
754
else{$B.$getattr(res, "__setitem__")(key, value)}
Sep 5, 2014
755
}catch(err){
756
if($B.is_exc(err, [_b_.StopIteration])){
Sep 5, 2014
757
return res
758
}
759
throw err
760
}
761
}
762
}
763
Feb 11, 2018
764
dict.get = function(){
Mar 7, 2018
765
var $ = $B.args("get", 3, {self: null, key: null, _default: null},
766
["self", "key", "_default"], arguments, {_default: $N}, null, null)
Feb 11, 2018
768
try{return dict.__getitem__($.self, $.key)}
769
catch(err){
770
if(_b_.isinstance(err, _b_.KeyError)){return $._default}
771
else{throw err}
772
}
773
}
774
775
var dict_items = $B.make_view("dict_items", true)
776
dict_items.$iterator = $B.make_iterator_class("dict_itemiterator")
777
Feb 11, 2018
778
dict.items = function(self){
Mar 23, 2018
779
if(arguments.length > 1){
780
var _len = arguments.length - 1,
781
_msg = "items() takes no arguments (" + _len + " given)"
782
throw _b_.TypeError.$factory(_msg)
783
}
784
var it = dict_items.$factory(to_list(self))
785
it.len_func = function(){return dict.__len__(self)}
786
return it
787
}
788
789
var dict_keys = $B.make_view("dict_keys", true)
790
dict_keys.$iterator = $B.make_iterator_class("dict_keyiterator")
Nov 21, 2015
791
Mar 23, 2018
793
if(arguments.length > 1){
794
var _len = arguments.length - 1,
795
_msg = "keys() takes no arguments (" + _len + " given)"
796
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
797
}
798
var it = dict_keys.$factory(to_list(self, 0))
799
it.len_func = function(){return dict.__len__(self)}
800
return it
Nov 21, 2015
801
}
802
Feb 11, 2018
803
dict.pop = function(){
Nov 21, 2015
804
805
var missing = {},
806
$ = $B.args("pop", 3, {self: null, key: null, _default: null},
807
["self", "key", "_default"], arguments, {_default: missing}, null, null),
808
self = $.self,
809
key = $.key,
810
_default = $._default
Nov 21, 2015
811
Sep 5, 2014
812
try{
813
var res = dict.__getitem__(self, key)
814
dict.__delitem__(self, key)
Sep 5, 2014
815
return res
816
}catch(err){
817
if(err.__class__ === _b_.KeyError){
818
if(_default !== missing){return _default}
Sep 5, 2014
819
throw err
820
}
821
throw err
822
}
823
}
824
Feb 11, 2018
825
dict.popitem = function(self){
827
var itm = _b_.next(_b_.iter(dict.items(self)))
828
dict.__delitem__(self, itm[0])
Feb 11, 2018
829
return _b_.tuple.$factory(itm)
831
if (err.__class__ == _b_.StopIteration) {
832
throw KeyError.$factory("'popitem(): dictionary is empty'")
Sep 5, 2014
835
}
836
Feb 11, 2018
837
dict.setdefault = function(){
Nov 21, 2015
838
Mar 7, 2018
839
var $ = $B.args("setdefault", 3, {self: null, key: null, _default: null},
840
["self", "key", "_default"], arguments, {_default: $N}, null, null),
841
self = $.self,
842
key = $.key,
843
_default = $._default
Nov 21, 2015
844
845
try{return dict.__getitem__(self, key)}
Sep 5, 2014
846
catch(err){
847
if(err.__class__ !== _b_.KeyError){
848
throw err
849
}
850
if(_default === undefined){_default = $N}
851
var hash = key.$hash
852
key.$hash = undefined
853
dict.$setitem(self, key, _default, hash)
Sep 5, 2014
854
return _default
855
}
856
}
857
Feb 11, 2018
858
dict.update = function(self){
Nov 21, 2015
859
Mar 7, 2018
860
var $ = $B.args("update", 1, {"self": null}, ["self"], arguments,
861
{}, "args", "kw"),
862
self = $.self,
863
args = $.args,
864
kw = $.kw
865
if(args.length > 0){
866
var o = args[0]
867
if(isinstance(o, dict)){
868
if(o.$jsobj){
869
o = jsobj2dict(o.$jsobj)
870
}
873
var _keys = _b_.list.$factory($B.$call($B.$getattr(o, "keys"))())
874
for(var i = 0, len = _keys.length; i < len; i++){
875
var _value = getattr(o, "__getitem__")(_keys[i])
876
dict.$setitem(self, _keys[i], _value)
877
}
878
}else{
879
var it = _b_.iter(o),
880
i = 0
881
while(true){
882
try{
883
var item = _b_.next(it)
884
}catch(err){
885
if(err.__class__ === _b_.StopIteration){break}
886
throw err
887
}
888
try{
889
key_value = _b_.list.$factory(item)
890
}catch(err){
891
throw _b_.TypeError.$factory("cannot convert dictionary" +
892
" update sequence element #" + i + " to a sequence")
893
}
894
if(key_value.length !== 2){
895
throw _b_.ValueError.$factory("dictionary update " +
896
"sequence element #" + i + " has length " +
897
key_value.length + "; 2 is required")
898
}
899
dict.$setitem(self, key_value[0], key_value[1])
900
i++
Sep 5, 2014
903
}
Sep 5, 2014
907
}
908
909
var dict_values = $B.make_view("dict_values")
910
dict_values.$iterator = $B.make_iterator_class("dict_valueiterator")
Nov 21, 2015
911
Feb 11, 2018
912
dict.values = function(self){
Mar 23, 2018
913
if(arguments.length > 1){
914
var _len = arguments.length - 1,
915
_msg = "values() takes no arguments (" + _len + " given)"
916
throw _b_.TypeError.$factory(_msg)
Nov 21, 2015
917
}
918
var it = dict_values.$factory(to_list(self, 1))
919
it.len_func = function(){return dict.__len__(self)}
920
return it
Nov 21, 2015
921
}
922
923
dict.$factory = function(){
924
var res = dict.__new__(dict)
925
var args = [res]
926
for(var i = 0, len = arguments.length; i < len ; i++){
927
args.push(arguments[i])
928
}
929
dict.__init__.apply(null, args)
Sep 5, 2014
930
return res
931
}
Sep 5, 2014
933
_b_.dict = dict
Feb 11, 2018
935
$B.set_func_names(dict, "builtins")
937
// This must be done after set_func_names, otherwise dict.fromkeys doesn't
938
// have the attribute $infos
939
dict.fromkeys = _b_.classmethod.$factory(dict.fromkeys)
940
941
// Class for attribute __dict__ of classes
942
var mappingproxy = $B.mappingproxy = $B.make_class("mappingproxy",
Feb 12, 2018
943
function(obj){
944
if(_b_.isinstance(obj, dict)){
945
// obj is a dictionary, with $string_dict table such that
946
// obj.$string_dict[key] = [value, rank]
947
// Transform it into an object with attribute $jsobj such that
948
// res.$jsobj[key] = value
949
var res = $B.obj_dict(dict.$to_obj(obj))
950
}else{
951
var res = $B.obj_dict(obj)
952
}
Feb 12, 2018
953
res.__class__ = mappingproxy
954
return res
955
}
956
)
Feb 12, 2018
958
mappingproxy.__setitem__ = function(){
Mar 7, 2018
959
throw _b_.TypeError.$factory("'mappingproxy' object does not support " +
960
"item assignment")
963
for(var attr in dict){
964
if(mappingproxy[attr] !== undefined ||
965
["__class__", "__mro__", "__new__", "__init__", "__delitem__",
966
"clear", "fromkeys", "pop", "popitem", "setdefault",
967
"update"].indexOf(attr) > -1){
968
continue
969
}
970
if(typeof dict[attr] == "function"){
971
mappingproxy[attr] = (function(key){
972
return function(){
973
return dict[key].apply(null, arguments)
974
}
975
})(attr)
976
}else{
977
mappingproxy[attr] = dict[attr]
978
}
979
}
980
Feb 12, 2018
981
$B.set_func_names(mappingproxy, "builtins")
Feb 11, 2018
984
var d = dict.$factory()
Mar 7, 2018
986
if(attr.charAt(0) != "$" && attr !== "__class__"){
987
if(x[attr] === undefined){
988
continue
989
}else if(x[attr].$jsobj === x){
990
d.$string_dict[attr] = [d, d.$version]
992
d.$string_dict[attr] = [x[attr], d.$version]
994
d.$version++
1000
$B.obj_dict = function(obj, from_js){
1001
var klass = obj.__class__ || $B.get_class(obj)
1002
if(klass !== undefined && klass.$native){
1003
throw _b_.AttributeError.$factory(klass.__name__ +
1004
" has no attribute '__dict__'")}
Feb 11, 2018
1005
var res = dict.$factory()
1006
res.$jsobj = obj
1007
res.$from_js = from_js // set to true if
1008
return res
1009
}
1010
Sep 5, 2014
1011
})(__BRYTHON__)